]> git.saurik.com Git - wxWidgets.git/blob - src/common/bmpcboxcmn.cpp
Don't recurse into top level children in wxWindow::FindWindow().
[wxWidgets.git] / src / common / bmpcboxcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/bmpcboxcmn.cpp
3 // Purpose: wxBitmapComboBox
4 // Author: Jaakko Salli
5 // Created: 2008-04-09
6 // Copyright: (c) 2008 Jaakko Salli
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #include "wx/bmpcbox.h"
25
26 #if wxUSE_BITMAPCOMBOBOX
27
28 #ifndef WX_PRECOMP
29 #include "wx/log.h"
30 #include "wx/dc.h"
31 #include "wx/ctrlsub.h"
32 #endif
33
34 #include "wx/settings.h"
35
36 // For wxODCB_XXX flags
37 #include "wx/odcombo.h"
38
39
40 const char wxBitmapComboBoxNameStr[] = "bitmapComboBox";
41
42 #if defined(wxBITMAPCOMBOBOX_OWNERDRAWN_BASED)
43
44 #define IMAGE_SPACING_RIGHT 4 // Space left of image
45
46 #define IMAGE_SPACING_LEFT 4 // Space right of image, left of text
47
48 #define EXTRA_FONT_HEIGHT 0 // Add to increase min. height of list items
49
50 #define wxBCB_DEFAULT_ITEM_HEIGHT 13
51
52
53 // This macros allows wxArrayPtrVoid to be used in more convenient manner
54 #define GetBitmapPtr(n) ((wxBitmap*)m_bitmaps[n])
55
56
57 // ----------------------------------------------------------------------------
58 // Initialization
59 // ----------------------------------------------------------------------------
60
61 void wxBitmapComboBoxBase::Init()
62 {
63 m_fontHeight = 0;
64 m_imgAreaWidth = 0;
65 m_indent = 0;
66 m_usedImgSize = wxSize(-1, -1);
67 }
68
69 void wxBitmapComboBoxBase::UpdateInternals()
70 {
71 m_fontHeight = GetControl()->GetCharHeight() + EXTRA_FONT_HEIGHT;
72
73 while ( m_bitmaps.GetCount() < GetItemContainer()->GetCount() )
74 m_bitmaps.Add( new wxBitmap() );
75 }
76
77 // ----------------------------------------------------------------------------
78 // Item manipulation
79 // ----------------------------------------------------------------------------
80
81 void wxBitmapComboBoxBase::DoSetItemBitmap(unsigned int n, const wxBitmap& bitmap)
82 {
83 wxCHECK_RET( n < m_bitmaps.size(), "invalid item index" );
84 *GetBitmapPtr(n) = bitmap;
85 }
86
87 wxBitmap wxBitmapComboBoxBase::GetItemBitmap(unsigned int n) const
88 {
89 wxCHECK_MSG( n < m_bitmaps.size(), wxNullBitmap, "invalid item index" );
90 return *GetBitmapPtr(n);
91 }
92
93 // ----------------------------------------------------------------------------
94 // wxItemContainer methods
95 // ----------------------------------------------------------------------------
96
97 void wxBitmapComboBoxBase::BCBDoClear()
98 {
99 for ( unsigned i = 0; i < m_bitmaps.size(); i++ )
100 delete GetBitmapPtr(i);
101
102 m_bitmaps.Empty();
103
104 m_usedImgSize.x = -1;
105 m_usedImgSize.y = -1;
106
107 DetermineIndent();
108 }
109
110 void wxBitmapComboBoxBase::BCBDoDeleteOneItem(unsigned int n)
111 {
112 delete GetBitmapPtr(n);
113 m_bitmaps.RemoveAt(n);
114 }
115
116 // ----------------------------------------------------------------------------
117 // Preparation and Calculations
118 // ----------------------------------------------------------------------------
119
120 bool wxBitmapComboBoxBase::OnAddBitmap(const wxBitmap& bitmap)
121 {
122 if ( bitmap.IsOk() )
123 {
124 int width = bitmap.GetWidth();
125 int height = bitmap.GetHeight();
126
127 if ( m_usedImgSize.x < 0 )
128 {
129 // If size not yet determined, get it from this image.
130 m_usedImgSize.x = width;
131 m_usedImgSize.y = height;
132
133 // Adjust control size to vertically fit the bitmap
134 wxWindow* ctrl = GetControl();
135 ctrl->InvalidateBestSize();
136 wxSize newSz = ctrl->GetBestSize();
137 wxSize sz = ctrl->GetSize();
138 if ( newSz.y > sz.y )
139 ctrl->SetSize(sz.x, newSz.y);
140 else
141 DetermineIndent();
142 }
143
144 wxCHECK_MSG( width == m_usedImgSize.x && height == m_usedImgSize.y,
145 false,
146 "you can only add images of same size" );
147
148 return true;
149 }
150
151 return false;
152 }
153
154 int wxBitmapComboBoxBase::DetermineIndent()
155 {
156 // Recalculate amount of empty space needed in front of
157 // text in control itself.
158 int indent = m_imgAreaWidth = 0;
159
160 if ( m_usedImgSize.x > 0 )
161 {
162 indent = m_usedImgSize.x + IMAGE_SPACING_LEFT + IMAGE_SPACING_RIGHT;
163 m_imgAreaWidth = indent;
164
165 indent -= 3;
166 }
167
168 return indent;
169 }
170
171 // ----------------------------------------------------------------------------
172 // Item drawing and measuring
173 // ----------------------------------------------------------------------------
174
175 void wxBitmapComboBoxBase::DrawBackground(wxDC& dc,
176 const wxRect& rect,
177 int WXUNUSED(item),
178 int flags) const
179 {
180 if ( flags & wxODCB_PAINTING_SELECTED )
181 {
182 const int vSizeDec = 0; // Vertical size reduction of selection rectangle edges
183
184 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHTTEXT));
185
186 wxColour selCol = wxSystemSettings::GetColour(wxSYS_COLOUR_HIGHLIGHT);
187 dc.SetPen(selCol);
188 dc.SetBrush(selCol);
189 dc.DrawRectangle(rect.x,
190 rect.y+vSizeDec,
191 rect.width,
192 rect.height-(vSizeDec*2));
193 }
194 else
195 {
196 dc.SetTextForeground(wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOWTEXT));
197
198 wxColour selCol = wxSystemSettings::GetColour(wxSYS_COLOUR_WINDOW);
199 dc.SetPen(selCol);
200 dc.SetBrush(selCol);
201 dc.DrawRectangle(rect);
202 }
203 }
204
205 void wxBitmapComboBoxBase::DrawItem(wxDC& dc,
206 const wxRect& rect,
207 int item,
208 const wxString& text,
209 int WXUNUSED(flags)) const
210 {
211 const wxBitmap& bmp = *GetBitmapPtr(item);
212 if ( bmp.IsOk() )
213 {
214 wxCoord w = bmp.GetWidth();
215 wxCoord h = bmp.GetHeight();
216
217 // Draw the image centered
218 dc.DrawBitmap(bmp,
219 rect.x + (m_usedImgSize.x-w)/2 + IMAGE_SPACING_LEFT,
220 rect.y + (rect.height-h)/2,
221 true);
222 }
223
224 if ( !text.empty() )
225 dc.DrawText(text,
226 rect.x + m_imgAreaWidth + 1,
227 rect.y + (rect.height-dc.GetCharHeight())/2);
228 }
229
230 wxCoord wxBitmapComboBoxBase::MeasureItem(size_t WXUNUSED(item)) const
231 {
232 if ( m_usedImgSize.y >= 0 )
233 {
234 int imgHeightArea = m_usedImgSize.y + 2;
235 return imgHeightArea > m_fontHeight ? imgHeightArea : m_fontHeight;
236 }
237
238 return wxBCB_DEFAULT_ITEM_HEIGHT;
239 }
240
241 #endif // wxBITMAPCOMBOBOX_OWNERDRAWN_BASED
242
243 #endif // wxUSE_BITMAPCOMBOBOX