]> git.saurik.com Git - wxWidgets.git/blame - src/generic/bmpcboxg.cpp
Make wxOwnerDrawnComboBox::DoGetBestSize() twice as fast.
[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
95a46303
RR
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"
84140dc9 37#include "wx/dc.h"
95a46303
RR
38
39#if wxUSE_IMAGE
40 #include "wx/image.h"
41#endif
42
43
95a46303
RR
44#define IMAGE_SPACING_CTRL_VERTICAL 7 // Spacing used in control size calculation
45
95a46303
RR
46
47// ============================================================================
48// implementation
49// ============================================================================
50
51
52BEGIN_EVENT_TABLE(wxBitmapComboBox, wxOwnerDrawnComboBox)
012967ef 53 EVT_SIZE(wxBitmapComboBox::OnSize)
95a46303
RR
54END_EVENT_TABLE()
55
56
57IMPLEMENT_DYNAMIC_CLASS(wxBitmapComboBox, wxOwnerDrawnComboBox)
58
59void wxBitmapComboBox::Init()
60{
95a46303
RR
61 m_inResize = false;
62}
63
64wxBitmapComboBox::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
81bool 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
f696015c 99 UpdateInternals();
95a46303
RR
100
101 return true;
102}
103
104bool 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
f696015c 123 UpdateInternals();
95a46303
RR
124
125 return true;
126}
127
95a46303
RR
128wxBitmapComboBox::~wxBitmapComboBox()
129{
bd0fa687 130 DoClear();
95a46303
RR
131}
132
133// ----------------------------------------------------------------------------
134// Item manipulation
135// ----------------------------------------------------------------------------
136
137void wxBitmapComboBox::SetItemBitmap(unsigned int n, const wxBitmap& bitmap)
138{
95a46303 139 OnAddBitmap(bitmap);
f696015c 140 DoSetItemBitmap(n, bitmap);
95a46303
RR
141
142 if ( (int)n == GetSelection() )
143 Refresh();
144}
145
a236aa20
VZ
146int 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
befee9b7
JS
153 wxASSERT( numItems == 1 || !HasFlag(wxCB_SORT) ); // Sanity check
154
a236aa20
VZ
155 m_bitmaps.Alloc(countNew);
156
f696015c 157 for ( unsigned int i = 0; i < numItems; i++ )
a236aa20
VZ
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 {
f696015c
VZ
167 for ( int i = numItems-1; i >= 0; i-- )
168 BCBDoDeleteOneItem(pos + i);
a236aa20 169 }
befee9b7
JS
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 }
f696015c 178
a236aa20
VZ
179 return index;
180}
181
182int 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
190int 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
199int 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
208int 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
95a46303
RR
218int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
219 unsigned int pos, void *clientData)
220{
a236aa20
VZ
221 const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData);
222 if(n != wxNOT_FOUND)
223 SetItemBitmap(n, bitmap);
95a46303
RR
224 return n;
225}
226
227int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
228 unsigned int pos, wxClientData *clientData)
229{
a236aa20
VZ
230 const int n = wxOwnerDrawnComboBox::Insert(item, pos, clientData);
231 if(n != wxNOT_FOUND)
232 SetItemBitmap(n, bitmap);
95a46303
RR
233 return n;
234}
235
a236aa20 236void wxBitmapComboBox::DoClear()
95a46303 237{
a236aa20 238 wxOwnerDrawnComboBox::DoClear();
f696015c 239 wxBitmapComboBoxBase::BCBDoClear();
95a46303
RR
240}
241
a236aa20 242void wxBitmapComboBox::DoDeleteOneItem(unsigned int n)
95a46303 243{
a236aa20 244 wxOwnerDrawnComboBox::DoDeleteOneItem(n);
f696015c 245 wxBitmapComboBoxBase::BCBDoDeleteOneItem(n);
95a46303
RR
246}
247
248// ----------------------------------------------------------------------------
249// wxBitmapComboBox event handlers and such
250// ----------------------------------------------------------------------------
251
012967ef 252void wxBitmapComboBox::OnSize(wxSizeEvent& event)
95a46303
RR
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
265wxSize wxBitmapComboBox::DoGetBestSize() const
266{
267 wxSize sz = wxOwnerDrawnComboBox::DoGetBestSize();
268
f696015c
VZ
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;
95a46303 273
f696015c
VZ
274 if ( h2 > sz.y )
275 sz.y = h2;
276
277 CacheBestSize(sz);
278 }
95a46303 279
95a46303
RR
280 return sz;
281}
282
283// ----------------------------------------------------------------------------
284// wxBitmapComboBox miscellaneous
285// ----------------------------------------------------------------------------
286
287bool wxBitmapComboBox::SetFont(const wxFont& font)
288{
289 bool res = wxOwnerDrawnComboBox::SetFont(font);
f696015c 290 UpdateInternals();
95a46303
RR
291 return res;
292}
293
294// ----------------------------------------------------------------------------
295// wxBitmapComboBox item drawing and measuring
296// ----------------------------------------------------------------------------
297
298void 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) ||
c905c0d6
VZ
305 item < 0 ||
306 ( (flags & wxODCB_PAINTING_CONTROL) && (GetInternalFlags() & wxCC_FULL_BUTTON)) )
95a46303
RR
307 {
308 wxOwnerDrawnComboBox::OnDrawBackground(dc, rect, item, flags);
309 return;
310 }
311
f696015c 312 wxBitmapComboBoxBase::DrawBackground(dc, rect, item, flags);
95a46303
RR
313}
314
315void wxBitmapComboBox::OnDrawItem(wxDC& dc,
316 const wxRect& rect,
317 int item,
318 int flags) const
319{
320 wxString text;
321 int imgAreaWidth = m_imgAreaWidth;
95a46303
RR
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();
f696015c
VZ
332 if ( !HasFlag(wxCB_READONLY) )
333 text.clear();
95a46303
RR
334 }
335 else
336 {
337 text = GetString(item);
95a46303 338 }
03647350 339
f696015c 340 wxBitmapComboBoxBase::DrawItem(dc, rect, item, text, flags);
95a46303
RR
341}
342
f696015c 343wxCoord wxBitmapComboBox::OnMeasureItem(size_t item) const
95a46303 344{
f696015c 345 return wxBitmapComboBoxBase::MeasureItem(item);
95a46303
RR
346}
347
348wxCoord 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