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