defer queue-resize until after size-allocate processing, to keep it from being ignore...
[wxWidgets.git] / src / gtk / bmpcbox.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/bmpcbox.cpp
3 // Purpose: wxBitmapComboBox
4 // Author: Jaakko Salli
5 // Created: 2008-05-19
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 #if wxUSE_BITMAPCOMBOBOX
26
27 #include "wx/bmpcbox.h"
28
29 #ifndef WX_PRECOMP
30 #include "wx/log.h"
31 #endif
32
33 #include "wx/gtk/private.h"
34
35 // ============================================================================
36 // implementation
37 // ============================================================================
38
39
40 IMPLEMENT_DYNAMIC_CLASS(wxBitmapComboBox, wxComboBox)
41
42
43 // ----------------------------------------------------------------------------
44 // wxBitmapComboBox creation
45 // ----------------------------------------------------------------------------
46
47 void wxBitmapComboBox::Init()
48 {
49 m_bitmapCellIndex = 0;
50 m_stringCellIndex = 1;
51 m_bitmapSize = wxSize(-1, -1);
52 }
53
54 wxBitmapComboBox::wxBitmapComboBox(wxWindow *parent,
55 wxWindowID id,
56 const wxString& value,
57 const wxPoint& pos,
58 const wxSize& size,
59 const wxArrayString& choices,
60 long style,
61 const wxValidator& validator,
62 const wxString& name)
63 : wxComboBox(),
64 wxBitmapComboBoxBase()
65 {
66 Init();
67
68 Create(parent,id,value,pos,size,choices,style,validator,name);
69 }
70
71 bool wxBitmapComboBox::Create(wxWindow *parent,
72 wxWindowID id,
73 const wxString& value,
74 const wxPoint& pos,
75 const wxSize& size,
76 const wxArrayString& choices,
77 long style,
78 const wxValidator& validator,
79 const wxString& name)
80 {
81 wxCArrayString chs(choices);
82 return Create(parent, id, value, pos, size, chs.GetCount(),
83 chs.GetStrings(), style, validator, name);
84 }
85
86 bool wxBitmapComboBox::Create(wxWindow *parent,
87 wxWindowID id,
88 const wxString& value,
89 const wxPoint& pos,
90 const wxSize& size,
91 int n,
92 const wxString choices[],
93 long style,
94 const wxValidator& validator,
95 const wxString& name)
96 {
97 if ( !wxComboBox::Create(parent, id, value, pos, size,
98 n, choices, style, validator, name) )
99 return false;
100
101 // Select 'value' in entry-less mode
102 if ( !GetEntry() )
103 {
104 int n = FindString(value);
105 if ( n != wxNOT_FOUND )
106 SetSelection(n);
107 }
108
109 return true;
110 }
111
112 void wxBitmapComboBox::GTKCreateComboBoxWidget()
113 {
114 GtkListStore *store;
115
116 store = gtk_list_store_new( 2, G_TYPE_OBJECT, G_TYPE_STRING );
117
118 if ( HasFlag(wxCB_READONLY) )
119 {
120 m_widget = gtk_combo_box_new_with_model( GTK_TREE_MODEL(store) );
121 }
122 else
123 {
124 m_widget = gtk_combo_box_entry_new_with_model( GTK_TREE_MODEL(store), m_stringCellIndex );
125 m_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(m_widget)));
126 gtk_editable_set_editable(GTK_EDITABLE(m_entry), true);
127 }
128 g_object_ref(m_widget);
129
130 // This must be called as gtk_combo_box_entry_new_with_model adds
131 // automatically adds one text column.
132 gtk_cell_layout_clear( GTK_CELL_LAYOUT(m_widget) );
133
134 GtkCellRenderer* imageRenderer = gtk_cell_renderer_pixbuf_new();
135 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(m_widget),
136 imageRenderer, FALSE);
137 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(m_widget),
138 imageRenderer, "pixbuf", 0);
139
140 GtkCellRenderer* textRenderer = gtk_cell_renderer_text_new();
141 gtk_cell_layout_pack_end( GTK_CELL_LAYOUT(m_widget),
142 textRenderer, TRUE );
143 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(m_widget),
144 textRenderer, "text", 1);
145 }
146
147 wxBitmapComboBox::~wxBitmapComboBox()
148 {
149 }
150
151 GtkWidget* wxBitmapComboBox::GetConnectWidget()
152 {
153 if ( GetEntry() )
154 return wxComboBox::GetConnectWidget();
155
156 return wxChoice::GetConnectWidget();
157 }
158
159 GdkWindow *wxBitmapComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
160 {
161 if ( GetEntry() )
162 return wxComboBox::GTKGetWindow(windows);
163
164 return wxChoice::GTKGetWindow(windows);
165 }
166
167 wxSize wxBitmapComboBox::DoGetBestSize() const
168 {
169 wxSize best = wxComboBox::DoGetBestSize();
170
171 int delta = GetBitmapSize().y - GetCharHeight();
172 if ( delta > 0 )
173 {
174 best.y += delta;
175 CacheBestSize(best);
176 }
177 return best;
178 }
179
180 // ----------------------------------------------------------------------------
181 // Item manipulation
182 // ----------------------------------------------------------------------------
183
184 void wxBitmapComboBox::SetItemBitmap(unsigned int n, const wxBitmap& bitmap)
185 {
186 if ( bitmap.IsOk() )
187 {
188 if ( m_bitmapSize.x < 0 )
189 {
190 m_bitmapSize.x = bitmap.GetWidth();
191 m_bitmapSize.y = bitmap.GetHeight();
192 }
193
194 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
195 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
196 GtkTreeIter iter;
197
198 if ( gtk_tree_model_iter_nth_child( model, &iter, NULL, n ) )
199 {
200 GValue value0 = { 0, };
201 g_value_init( &value0, G_TYPE_OBJECT );
202 g_value_set_object( &value0, bitmap.GetPixbuf() );
203 gtk_list_store_set_value( GTK_LIST_STORE(model), &iter,
204 m_bitmapCellIndex, &value0 );
205 g_value_unset( &value0 );
206 }
207 }
208 }
209
210 wxBitmap wxBitmapComboBox::GetItemBitmap(unsigned int n) const
211 {
212 wxBitmap bitmap;
213
214 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
215 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
216 GtkTreeIter iter;
217
218 if (gtk_tree_model_iter_nth_child (model, &iter, NULL, n))
219 {
220 GValue value = { 0, };
221 gtk_tree_model_get_value( model, &iter,
222 m_bitmapCellIndex, &value );
223 GdkPixbuf* pixbuf = (GdkPixbuf*) g_value_get_object( &value );
224 if ( pixbuf )
225 {
226 g_object_ref( pixbuf );
227 bitmap = wxBitmap(pixbuf);
228 }
229 g_value_unset( &value );
230 }
231
232 return bitmap;
233 }
234
235 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap)
236 {
237 const int n = wxComboBox::Append(item);
238 if ( n != wxNOT_FOUND )
239 SetItemBitmap(n, bitmap);
240 return n;
241 }
242
243 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
244 void *clientData)
245 {
246 const int n = wxComboBox::Append(item, clientData);
247 if ( n != wxNOT_FOUND )
248 SetItemBitmap(n, bitmap);
249 return n;
250 }
251
252 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
253 wxClientData *clientData)
254 {
255 const int n = wxComboBox::Append(item, clientData);
256 if ( n != wxNOT_FOUND )
257 SetItemBitmap(n, bitmap);
258 return n;
259 }
260
261 int wxBitmapComboBox::Insert(const wxString& item,
262 const wxBitmap& bitmap,
263 unsigned int pos)
264 {
265 const int n = wxComboBox::Insert(item, pos);
266 if ( n != wxNOT_FOUND )
267 SetItemBitmap(n, bitmap);
268 return n;
269 }
270
271 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
272 unsigned int pos, wxClientData *clientData)
273 {
274 const int n = wxComboBox::Insert(item, pos, clientData);
275 if ( n != wxNOT_FOUND )
276 SetItemBitmap(n, bitmap);
277 return n;
278 }
279
280 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
281 unsigned int pos, void *clientData)
282 {
283 const int n = wxComboBox::Insert(item, pos, clientData);
284 if ( n != wxNOT_FOUND )
285 SetItemBitmap(n, bitmap);
286 return n;
287 }
288
289 void wxBitmapComboBox::GTKInsertComboBoxTextItem( unsigned int n, const wxString& text )
290 {
291 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
292 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
293 GtkListStore *store = GTK_LIST_STORE( model );
294 GtkTreeIter iter;
295
296 gtk_list_store_insert( store, &iter, n );
297
298 GValue value = { 0, };
299 g_value_init( &value, G_TYPE_STRING );
300 g_value_set_string( &value, wxGTK_CONV( text ) );
301 gtk_list_store_set_value( store, &iter, m_stringCellIndex, &value );
302 g_value_unset( &value );
303 }
304
305 // ----------------------------------------------------------------------------
306 // wxTextEntry interface override
307 // ----------------------------------------------------------------------------
308
309 void wxBitmapComboBox::WriteText(const wxString& value)
310 {
311 if ( GetEntry() )
312 wxComboBox::WriteText(value);
313 else
314 SetStringSelection(value);
315 }
316
317 wxString wxBitmapComboBox::GetValue() const
318 {
319 if ( GetEntry() )
320 return wxComboBox::GetValue();
321
322 return GetStringSelection();
323 }
324
325 void wxBitmapComboBox::Remove(long from, long to)
326 {
327 if ( GetEntry() )
328 wxComboBox::Remove(from, to);
329 }
330
331 void wxBitmapComboBox::SetInsertionPoint(long pos)
332 {
333 if ( GetEntry() )
334 wxComboBox::SetInsertionPoint(pos);
335 }
336
337 long wxBitmapComboBox::GetInsertionPoint() const
338 {
339 if ( GetEntry() )
340 return wxComboBox::GetInsertionPoint();
341
342 return 0;
343 }
344 long wxBitmapComboBox::GetLastPosition() const
345 {
346 if ( GetEntry() )
347 return wxComboBox::GetLastPosition();
348
349 return 0;
350 }
351
352 void wxBitmapComboBox::SetSelection(long from, long to)
353 {
354 if ( GetEntry() )
355 wxComboBox::SetSelection(from, to);
356 }
357
358 void wxBitmapComboBox::GetSelection(long *from, long *to) const
359 {
360 if ( GetEntry() )
361 wxComboBox::GetSelection(from, to);
362 }
363
364 bool wxBitmapComboBox::IsEditable() const
365 {
366 if ( GetEntry() )
367 return wxTextEntry::IsEditable();
368
369 return false;
370 }
371
372 void wxBitmapComboBox::SetEditable(bool editable)
373 {
374 if ( GetEntry() )
375 wxComboBox::SetEditable(editable);
376 }
377
378 #endif // wxUSE_BITMAPCOMBOBOX