1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/bmpcboxcmn.cpp
3 // Purpose: wxBitmapComboBox
4 // Author: Jaakko Salli
7 // Copyright: (c) 2008 Jaakko Salli
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 #include "wx/wxprec.h"
25 #include "wx/bmpcbox.h"
27 #if wxUSE_BITMAPCOMBOBOX
32 #include "wx/ctrlsub.h"
35 #include "wx/settings.h"
37 // For wxODCB_XXX flags
38 #include "wx/odcombo.h"
41 const wxChar wxBitmapComboBoxNameStr
[] = wxT("bitmapComboBox");
43 #if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
45 #define IMAGE_SPACING_RIGHT 4 // Space left of image
47 #define IMAGE_SPACING_LEFT 4 // Space right of image, left of text
49 #define EXTRA_FONT_HEIGHT 0 // Add to increase min. height of list items
51 #define wxBCB_DEFAULT_ITEM_HEIGHT 13
54 // This macros allows wxArrayPtrVoid to be used in more convenient manner
55 #define GetBitmapPtr(n) ((wxBitmap*)m_bitmaps[n])
58 // ----------------------------------------------------------------------------
60 // ----------------------------------------------------------------------------
62 void wxBitmapComboBoxBase::Init()
67 m_usedImgSize
= wxSize(-1, -1);
70 void wxBitmapComboBoxBase::UpdateInternals()
72 m_fontHeight
= GetControl()->GetCharHeight() + EXTRA_FONT_HEIGHT
;
74 while ( m_bitmaps
.GetCount() < GetItemContainer()->GetCount() )
75 m_bitmaps
.Add( new wxBitmap() );
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 void wxBitmapComboBoxBase::DoSetItemBitmap(unsigned int n
, const wxBitmap
& bitmap
)
84 wxCHECK_RET( n
< m_bitmaps
.size(), "invalid item index" );
85 *GetBitmapPtr(n
) = bitmap
;
88 wxBitmap
wxBitmapComboBoxBase::GetItemBitmap(unsigned int n
) const
90 wxCHECK_MSG( n
< m_bitmaps
.size(), wxNullBitmap
, "invalid item index" );
91 return *GetBitmapPtr(n
);
94 // ----------------------------------------------------------------------------
95 // wxItemContainer methods
96 // ----------------------------------------------------------------------------
98 void wxBitmapComboBoxBase::BCBDoClear()
100 for ( unsigned i
= 0; i
< m_bitmaps
.size(); i
++ )
101 delete GetBitmapPtr(i
);
105 m_usedImgSize
.x
= -1;
106 m_usedImgSize
.y
= -1;
111 void wxBitmapComboBoxBase::BCBDoDeleteOneItem(unsigned int n
)
113 delete GetBitmapPtr(n
);
114 m_bitmaps
.RemoveAt(n
);
117 // ----------------------------------------------------------------------------
118 // Preparation and Calculations
119 // ----------------------------------------------------------------------------
121 bool wxBitmapComboBoxBase::OnAddBitmap(const wxBitmap
& bitmap
)
125 int width
= bitmap
.GetWidth();
126 int height
= bitmap
.GetHeight();
128 if ( m_usedImgSize
.x
< 0 )
130 // If size not yet determined, get it from this image.
131 m_usedImgSize
.x
= width
;
132 m_usedImgSize
.y
= height
;
134 // Adjust control size to vertically fit the bitmap
135 wxWindow
* ctrl
= GetControl();
136 ctrl
->InvalidateBestSize();
137 wxSize newSz
= ctrl
->GetBestSize();
138 wxSize sz
= ctrl
->GetSize();
139 if ( newSz
.y
> sz
.y
)
140 ctrl
->SetSize(sz
.x
, newSz
.y
);
145 wxCHECK_MSG( width
== m_usedImgSize
.x
&& height
== m_usedImgSize
.y
,
147 "you can only add images of same size" );
155 int wxBitmapComboBoxBase::DetermineIndent()
157 // Recalculate amount of empty space needed in front of
158 // text in control itself.
159 int indent
= m_imgAreaWidth
= 0;
161 if ( m_usedImgSize
.x
> 0 )
163 indent
= m_usedImgSize
.x
+ IMAGE_SPACING_LEFT
+ IMAGE_SPACING_RIGHT
;
164 m_imgAreaWidth
= indent
;
172 // ----------------------------------------------------------------------------
173 // Item drawing and measuring
174 // ----------------------------------------------------------------------------
176 void wxBitmapComboBoxBase::DrawBackground(wxDC
& dc
,
181 if ( flags
& wxODCB_PAINTING_SELECTED
)
183 const int vSizeDec
= 0; // Vertical size reduction of selection rectangle edges
185 dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT
));
187 wxColour selCol
= wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT
);
190 dc
.DrawRectangle(rect
.x
,
193 rect
.height
-(vSizeDec
*2));
197 dc
.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT
));
199 wxColour selCol
= wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW
);
202 dc
.DrawRectangle(rect
);
206 void wxBitmapComboBoxBase::DrawItem(wxDC
& dc
,
209 const wxString
& text
,
210 int WXUNUSED(flags
)) const
212 const wxBitmap
& bmp
= *GetBitmapPtr(item
);
215 wxCoord w
= bmp
.GetWidth();
216 wxCoord h
= bmp
.GetHeight();
218 // Draw the image centered
220 rect
.x
+ (m_usedImgSize
.x
-w
)/2 + IMAGE_SPACING_LEFT
,
221 rect
.y
+ (rect
.height
-h
)/2,
227 rect
.x
+ m_imgAreaWidth
+ 1,
228 rect
.y
+ (rect
.height
-dc
.GetCharHeight())/2);
231 wxCoord
wxBitmapComboBoxBase::MeasureItem(size_t WXUNUSED(item
)) const
233 if ( m_usedImgSize
.y
>= 0 )
235 int imgHeightArea
= m_usedImgSize
.y
+ 2;
236 return imgHeightArea
> m_fontHeight
? imgHeightArea
: m_fontHeight
;
239 return wxBCB_DEFAULT_ITEM_HEIGHT
;
242 #endif // wxBITMAPCOMBOBOX_OWNERDRAWN_BASED
244 #endif // wxUSE_BITMAPCOMBOBOX