]> git.saurik.com Git - wxWidgets.git/blob - src/generic/bmpcboxg.cpp
Return NULL from wxWindow::GetCapture() when the capture is being lost.
[wxWidgets.git] / src / generic / bmpcboxg.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/generic/bmpcboxg.cpp
3 // Purpose: wxBitmapComboBox
4 // Author: Jaakko Salli
5 // Modified by:
6 // Created: Aug-31-2006
7 // Copyright: (c) 2005 Jaakko Salli
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
10
11 // ============================================================================
12 // declarations
13 // ============================================================================
14
15 // ----------------------------------------------------------------------------
16 // headers
17 // ----------------------------------------------------------------------------
18
19 #include "wx/wxprec.h"
20
21 #ifdef __BORLANDC__
22 #pragma hdrstop
23 #endif
24
25 #if wxUSE_BITMAPCOMBOBOX
26
27 #include "wx/bmpcbox.h"
28
29 #if defined(wxGENERIC_BITMAPCOMBOBOX)
30
31 #ifndef WX_PRECOMP
32 #include "wx/log.h"
33 #endif
34
35 #include "wx/odcombo.h"
36 #include "wx/settings.h"
37 #include "wx/dc.h"
38
39 #if wxUSE_IMAGE
40 #include "wx/image.h"
41 #endif
42
43
44 #define IMAGE_SPACING_CTRL_VERTICAL 7 // Spacing used in control size calculation
45
46
47 // ============================================================================
48 // implementation
49 // ============================================================================
50
51
52 BEGIN_EVENT_TABLE(wxBitmapComboBox, wxOwnerDrawnComboBox)
53 EVT_SIZE(wxBitmapComboBox::OnSize)
54 END_EVENT_TABLE()
55
56
57 IMPLEMENT_DYNAMIC_CLASS(wxBitmapComboBox, wxOwnerDrawnComboBox)
58
59 void wxBitmapComboBox::Init()
60 {
61 m_inResize = false;
62 }
63
64 wxBitmapComboBox::wxBitmapComboBox(wxWindow *parent,
65 wxWindowID id,
66 const wxString& value,
67 const wxPoint& pos,
68 const wxSize& size,
69 const wxArrayString& choices,
70 long style,
71 const wxValidator& validator,
72 const wxString& name)
73 : wxOwnerDrawnComboBox(),
74 wxBitmapComboBoxBase()
75 {
76 Init();
77
78 Create(parent,id,value,pos,size,choices,style,validator,name);
79 }
80
81 bool wxBitmapComboBox::Create(wxWindow *parent,
82 wxWindowID id,
83 const wxString& value,
84 const wxPoint& pos,
85 const wxSize& size,
86 const wxArrayString& choices,
87 long style,
88 const wxValidator& validator,
89 const wxString& name)
90 {
91 if ( !wxOwnerDrawnComboBox::Create(parent, id, value,
92 pos, size,
93 choices, style,
94 validator, name) )
95 {
96 return false;
97 }
98
99 UpdateInternals();
100
101 return true;
102 }
103
104 bool wxBitmapComboBox::Create(wxWindow *parent,
105 wxWindowID id,
106 const wxString& value,
107 const wxPoint& pos,
108 const wxSize& size,
109 int n,
110 const wxString choices[],
111 long style,
112 const wxValidator& validator,
113 const wxString& name)
114 {
115 if ( !wxOwnerDrawnComboBox::Create(parent, id, value,
116 pos, size, n,
117 choices, style,
118 validator, name) )
119 {
120 return false;
121 }
122
123 UpdateInternals();
124
125 return true;
126 }
127
128 wxBitmapComboBox::~wxBitmapComboBox()
129 {
130 DoClear();
131 }
132
133 // ----------------------------------------------------------------------------
134 // Item manipulation
135 // ----------------------------------------------------------------------------
136
137 void wxBitmapComboBox::SetItemBitmap(unsigned int n, const wxBitmap& bitmap)
138 {
139 OnAddBitmap(bitmap);
140 DoSetItemBitmap(n, bitmap);
141
142 if ( (int)n == GetSelection() )
143 Refresh();
144 }
145
146 int wxBitmapComboBox::DoInsertItems(const wxArrayStringsAdapter & items,
147 unsigned int pos,
148 void **clientData, wxClientDataType type)
149 {
150 const unsigned int numItems = items.GetCount();
151 const unsigned int countNew = GetCount() + numItems;
152
153 wxASSERT( numItems == 1 || !HasFlag(wxCB_SORT) ); // Sanity check
154
155 m_bitmaps.Alloc(countNew);
156
157 for ( unsigned int i = 0; i < numItems; i++ )
158 {
159 m_bitmaps.Insert(new wxBitmap(wxNullBitmap), pos + i);
160 }
161
162 const int index = wxOwnerDrawnComboBox::DoInsertItems(items, pos,
163 clientData, type);
164
165 if ( index == wxNOT_FOUND )
166 {
167 for ( int i = numItems-1; i >= 0; i-- )
168 BCBDoDeleteOneItem(pos + i);
169 }
170 else if ( ((unsigned int)index) != pos )
171 {
172 // Move pre-inserted empty bitmap into correct position
173 // (usually happens when combo box has wxCB_SORT style)
174 wxBitmap* bmp = static_cast<wxBitmap*>(m_bitmaps[pos]);
175 m_bitmaps.RemoveAt(pos);
176 m_bitmaps.Insert(bmp, index);
177 }
178
179 return index;
180 }
181
182 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap)
183 {
184 const int n = wxOwnerDrawnComboBox::Append(item);
185 if(n != wxNOT_FOUND)
186 SetItemBitmap(n, bitmap);
187 return n;
188 }
189
190 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
191 void *clientData)
192 {
193 const int n = wxOwnerDrawnComboBox::Append(item, clientData);
194 if(n != wxNOT_FOUND)
195 SetItemBitmap(n, bitmap);
196 return n;
197 }
198
199 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
200 wxClientData *clientData)
201 {
202 const int n = wxOwnerDrawnComboBox::Append(item, clientData);
203 if(n != wxNOT_FOUND)
204 SetItemBitmap(n, bitmap);
205 return n;
206 }
207
208 int wxBitmapComboBox::Insert(const wxString& item,
209 const wxBitmap& bitmap,
210 unsigned int pos)
211 {
212 const int n = wxOwnerDrawnComboBox::Insert(item, pos);
213 if(n != wxNOT_FOUND)
214 SetItemBitmap(n, bitmap);
215 return n;
216 }
217
218 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
219 unsigned int pos, void *clientData)
220 {
221 const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData);
222 if(n != wxNOT_FOUND)
223 SetItemBitmap(n, bitmap);
224 return n;
225 }
226
227 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
228 unsigned int pos, wxClientData *clientData)
229 {
230 const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData);
231 if(n != wxNOT_FOUND)
232 SetItemBitmap(n, bitmap);
233 return n;
234 }
235
236 void wxBitmapComboBox::DoClear()
237 {
238 wxOwnerDrawnComboBox::DoClear();
239 wxBitmapComboBoxBase::BCBDoClear();
240 }
241
242 void wxBitmapComboBox::DoDeleteOneItem(unsigned int n)
243 {
244 wxOwnerDrawnComboBox::DoDeleteOneItem(n);
245 wxBitmapComboBoxBase::BCBDoDeleteOneItem(n);
246 }
247
248 // ----------------------------------------------------------------------------
249 // wxBitmapComboBox event handlers and such
250 // ----------------------------------------------------------------------------
251
252 void wxBitmapComboBox::OnSize(wxSizeEvent& event)
253 {
254 // Prevent infinite looping
255 if ( !m_inResize )
256 {
257 m_inResize = true;
258 DetermineIndent();
259 m_inResize = false;
260 }
261
262 event.Skip();
263 }
264
265 wxSize wxBitmapComboBox::DoGetBestSize() const
266 {
267 wxSize sz = wxOwnerDrawnComboBox::DoGetBestSize();
268
269 if ( HasFlag(wxCB_READONLY) )
270 {
271 // Scale control to match height of highest image.
272 int h2 = m_usedImgSize.y + IMAGE_SPACING_CTRL_VERTICAL;
273
274 if ( h2 > sz.y )
275 sz.y = h2;
276
277 CacheBestSize(sz);
278 }
279
280 return sz;
281 }
282
283 // ----------------------------------------------------------------------------
284 // wxBitmapComboBox miscellaneous
285 // ----------------------------------------------------------------------------
286
287 bool wxBitmapComboBox::SetFont(const wxFont& font)
288 {
289 bool res = wxOwnerDrawnComboBox::SetFont(font);
290 UpdateInternals();
291 return res;
292 }
293
294 // ----------------------------------------------------------------------------
295 // wxBitmapComboBox item drawing and measuring
296 // ----------------------------------------------------------------------------
297
298 void wxBitmapComboBox::OnDrawBackground(wxDC& dc,
299 const wxRect& rect,
300 int item,
301 int flags) const
302 {
303 if ( GetCustomPaintWidth() == 0 ||
304 !(flags & wxODCB_PAINTING_SELECTED) ||
305 item < 0 ||
306 ( (flags & wxODCB_PAINTING_CONTROL) && (GetInternalFlags() & wxCC_FULL_BUTTON)) )
307 {
308 wxOwnerDrawnComboBox::OnDrawBackground(dc, rect, item, flags);
309 return;
310 }
311
312 wxBitmapComboBoxBase::DrawBackground(dc, rect, item, flags);
313 }
314
315 void wxBitmapComboBox::OnDrawItem(wxDC& dc,
316 const wxRect& rect,
317 int item,
318 int flags) const
319 {
320 wxString text;
321 int imgAreaWidth = m_imgAreaWidth;
322
323 if ( imgAreaWidth == 0 )
324 {
325 wxOwnerDrawnComboBox::OnDrawItem(dc, rect, item, flags);
326 return;
327 }
328
329 if ( flags & wxODCB_PAINTING_CONTROL )
330 {
331 text = GetValue();
332 if ( !HasFlag(wxCB_READONLY) )
333 text.clear();
334 }
335 else
336 {
337 text = GetString(item);
338 }
339
340 wxBitmapComboBoxBase::DrawItem(dc, rect, item, text, flags);
341 }
342
343 wxCoord wxBitmapComboBox::OnMeasureItem(size_t item) const
344 {
345 return wxBitmapComboBoxBase::MeasureItem(item);
346 }
347
348 wxCoord wxBitmapComboBox::OnMeasureItemWidth(size_t item) const
349 {
350 wxCoord x, y;
351 GetTextExtent(GetString(item), &x, &y, 0, 0);
352 x += m_imgAreaWidth;
353 return x;
354 }
355
356 #endif // defined(wxGENERIC_BITMAPCOMBOBOX)
357
358 #endif // wxUSE_BITMAPCOMBOBOX