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