1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/bmpcbox.cpp
3 // Purpose: wxBitmapComboBox
4 // Author: Jaakko Salli
5 // Created: 2008-05-19
6 // Copyright: (c) 2008 Jaakko Salli
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
9
10 // ============================================================================
11 // declarations
12 // ============================================================================
13
14 // ----------------------------------------------------------------------------
15 // headers
16 // ----------------------------------------------------------------------------
17
18 #include "wx/wxprec.h"
19
20 #ifdef __BORLANDC__
21 #pragma hdrstop
22 #endif
23
24 #if wxUSE_BITMAPCOMBOBOX
25
26 #include "wx/bmpcbox.h"
27
28 #ifndef WX_PRECOMP
29 #include "wx/log.h"
30 #endif
31
32 #include <gtk/gtk.h>
33 #include "wx/gtk/private.h"
34
35 // ============================================================================
36 // implementation
37 // ============================================================================
38
39
IMPLEMENT_DYNAMIC_CLASS(wxBitmapComboBox,wxComboBox)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
wxBitmapComboBox(wxWindow * parent,wxWindowID id,const wxString & value,const wxPoint & pos,const wxSize & size,const wxArrayString & choices,long style,const wxValidator & validator,const wxString & name)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
Create(wxWindow * parent,wxWindowID id,const wxString & value,const wxPoint & pos,const wxSize & size,const wxArrayString & choices,long style,const wxValidator & validator,const wxString & name)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
Create(wxWindow * parent,wxWindowID id,const wxString & value,const wxPoint & pos,const wxSize & size,int n,const wxString choices[],long style,const wxValidator & validator,const wxString & name)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 i = FindString(value);
105 if (i != wxNOT_FOUND)
106 SetSelection(i);
107 }
108
109 return true;
110 }
111
GTKCreateComboBoxWidget()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 #ifdef __WXGTK3__
125 m_widget = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store));
126 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(m_widget), m_stringCellIndex);
127 #else
128 m_widget = gtk_combo_box_entry_new_with_model( GTK_TREE_MODEL(store), m_stringCellIndex );
129 #endif
130 m_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(m_widget)));
131 g_object_add_weak_pointer(G_OBJECT(m_entry), (void**)&m_entry);
132 gtk_editable_set_editable(GTK_EDITABLE(m_entry), true);
133 }
134 g_object_ref(m_widget);
135
136 // This must be called as gtk_combo_box_entry_new_with_model adds
137 // automatically adds one text column.
138 gtk_cell_layout_clear( GTK_CELL_LAYOUT(m_widget) );
139
140 GtkCellRenderer* imageRenderer = gtk_cell_renderer_pixbuf_new();
141 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT(m_widget),
142 imageRenderer, FALSE);
143 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(m_widget),
144 imageRenderer, "pixbuf", 0);
145
146 GtkCellRenderer* textRenderer = gtk_cell_renderer_text_new();
147 gtk_cell_layout_pack_end( GTK_CELL_LAYOUT(m_widget),
148 textRenderer, TRUE );
149 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT(m_widget),
150 textRenderer, "text", 1);
151 }
152
~wxBitmapComboBox()153 wxBitmapComboBox::~wxBitmapComboBox()
154 {
155 }
156
GetConnectWidget()157 GtkWidget* wxBitmapComboBox::GetConnectWidget()
158 {
159 if ( GetEntry() )
160 return wxComboBox::GetConnectWidget();
161
162 return wxChoice::GetConnectWidget();
163 }
164
GTKGetWindow(wxArrayGdkWindows & windows) const165 GdkWindow *wxBitmapComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
166 {
167 if ( GetEntry() )
168 return wxComboBox::GTKGetWindow(windows);
169
170 return wxChoice::GTKGetWindow(windows);
171 }
172
DoGetBestSize() const173 wxSize wxBitmapComboBox::DoGetBestSize() const
174 {
175 wxSize best = wxComboBox::DoGetBestSize();
176
177 int delta = GetBitmapSize().y - GetCharHeight();
178 if ( delta > 0 )
179 {
180 best.y += delta;
181 CacheBestSize(best);
182 }
183 return best;
184 }
185
186 // ----------------------------------------------------------------------------
187 // Item manipulation
188 // ----------------------------------------------------------------------------
189
SetItemBitmap(unsigned int n,const wxBitmap & bitmap)190 void wxBitmapComboBox::SetItemBitmap(unsigned int n, const wxBitmap& bitmap)
191 {
192 if ( bitmap.IsOk() )
193 {
194 if ( m_bitmapSize.x < 0 )
195 {
196 m_bitmapSize.x = bitmap.GetWidth();
197 m_bitmapSize.y = bitmap.GetHeight();
198 }
199
200 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
201 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
202 GtkTreeIter iter;
203
204 if ( gtk_tree_model_iter_nth_child( model, &iter, NULL, n ) )
205 {
206 GValue value0 = G_VALUE_INIT;
207 g_value_init( &value0, G_TYPE_OBJECT );
208 g_value_set_object( &value0, bitmap.GetPixbuf() );
209 gtk_list_store_set_value( GTK_LIST_STORE(model), &iter,
210 m_bitmapCellIndex, &value0 );
211 g_value_unset( &value0 );
212 }
213 }
214 }
215
GetItemBitmap(unsigned int n) const216 wxBitmap wxBitmapComboBox::GetItemBitmap(unsigned int n) const
217 {
218 wxBitmap bitmap;
219
220 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
221 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
222 GtkTreeIter iter;
223
224 if (gtk_tree_model_iter_nth_child (model, &iter, NULL, n))
225 {
226 GValue value = G_VALUE_INIT;
227 gtk_tree_model_get_value( model, &iter,
228 m_bitmapCellIndex, &value );
229 GdkPixbuf* pixbuf = (GdkPixbuf*) g_value_get_object( &value );
230 if ( pixbuf )
231 {
232 g_object_ref( pixbuf );
233 bitmap = wxBitmap(pixbuf);
234 }
235 g_value_unset( &value );
236 }
237
238 return bitmap;
239 }
240
Append(const wxString & item,const wxBitmap & bitmap)241 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap)
242 {
243 const int n = wxComboBox::Append(item);
244 if ( n != wxNOT_FOUND )
245 SetItemBitmap(n, bitmap);
246 return n;
247 }
248
Append(const wxString & item,const wxBitmap & bitmap,void * clientData)249 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
250 void *clientData)
251 {
252 const int n = wxComboBox::Append(item, clientData);
253 if ( n != wxNOT_FOUND )
254 SetItemBitmap(n, bitmap);
255 return n;
256 }
257
Append(const wxString & item,const wxBitmap & bitmap,wxClientData * clientData)258 int wxBitmapComboBox::Append(const wxString& item, const wxBitmap& bitmap,
259 wxClientData *clientData)
260 {
261 const int n = wxComboBox::Append(item, clientData);
262 if ( n != wxNOT_FOUND )
263 SetItemBitmap(n, bitmap);
264 return n;
265 }
266
Insert(const wxString & item,const wxBitmap & bitmap,unsigned int pos)267 int wxBitmapComboBox::Insert(const wxString& item,
268 const wxBitmap& bitmap,
269 unsigned int pos)
270 {
271 const int n = wxComboBox::Insert(item, pos);
272 if ( n != wxNOT_FOUND )
273 SetItemBitmap(n, bitmap);
274 return n;
275 }
276
Insert(const wxString & item,const wxBitmap & bitmap,unsigned int pos,wxClientData * clientData)277 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
278 unsigned int pos, wxClientData *clientData)
279 {
280 const int n = wxComboBox::Insert(item, pos, clientData);
281 if ( n != wxNOT_FOUND )
282 SetItemBitmap(n, bitmap);
283 return n;
284 }
285
Insert(const wxString & item,const wxBitmap & bitmap,unsigned int pos,void * clientData)286 int wxBitmapComboBox::Insert(const wxString& item, const wxBitmap& bitmap,
287 unsigned int pos, void *clientData)
288 {
289 const int n = wxComboBox::Insert(item, pos, clientData);
290 if ( n != wxNOT_FOUND )
291 SetItemBitmap(n, bitmap);
292 return n;
293 }
294
GTKInsertComboBoxTextItem(unsigned int n,const wxString & text)295 void wxBitmapComboBox::GTKInsertComboBoxTextItem( unsigned int n, const wxString& text )
296 {
297 GtkComboBox* combobox = GTK_COMBO_BOX( m_widget );
298 GtkTreeModel *model = gtk_combo_box_get_model( combobox );
299 GtkListStore *store = GTK_LIST_STORE( model );
300 GtkTreeIter iter;
301
302 gtk_list_store_insert( store, &iter, n );
303
304 GValue value = G_VALUE_INIT;
305 g_value_init( &value, G_TYPE_STRING );
306 g_value_set_string( &value, wxGTK_CONV( text ) );
307 gtk_list_store_set_value( store, &iter, m_stringCellIndex, &value );
308 g_value_unset( &value );
309 }
310
311 // ----------------------------------------------------------------------------
312 // wxTextEntry interface override
313 // ----------------------------------------------------------------------------
314
WriteText(const wxString & value)315 void wxBitmapComboBox::WriteText(const wxString& value)
316 {
317 if ( GetEntry() )
318 wxComboBox::WriteText(value);
319 else
320 SetStringSelection(value);
321 }
322
GetValue() const323 wxString wxBitmapComboBox::GetValue() const
324 {
325 if ( GetEntry() )
326 return wxComboBox::GetValue();
327
328 return GetStringSelection();
329 }
330
Remove(long from,long to)331 void wxBitmapComboBox::Remove(long from, long to)
332 {
333 if ( GetEntry() )
334 wxComboBox::Remove(from, to);
335 }
336
SetInsertionPoint(long pos)337 void wxBitmapComboBox::SetInsertionPoint(long pos)
338 {
339 if ( GetEntry() )
340 wxComboBox::SetInsertionPoint(pos);
341 }
342
GetInsertionPoint() const343 long wxBitmapComboBox::GetInsertionPoint() const
344 {
345 if ( GetEntry() )
346 return wxComboBox::GetInsertionPoint();
347
348 return 0;
349 }
GetLastPosition() const350 long wxBitmapComboBox::GetLastPosition() const
351 {
352 if ( GetEntry() )
353 return wxComboBox::GetLastPosition();
354
355 return 0;
356 }
357
SetSelection(long from,long to)358 void wxBitmapComboBox::SetSelection(long from, long to)
359 {
360 if ( GetEntry() )
361 wxComboBox::SetSelection(from, to);
362 }
363
GetSelection(long * from,long * to) const364 void wxBitmapComboBox::GetSelection(long *from, long *to) const
365 {
366 if ( GetEntry() )
367 wxComboBox::GetSelection(from, to);
368 }
369
IsEditable() const370 bool wxBitmapComboBox::IsEditable() const
371 {
372 if ( GetEntry() )
373 return wxTextEntry::IsEditable();
374
375 return false;
376 }
377
SetEditable(bool editable)378 void wxBitmapComboBox::SetEditable(bool editable)
379 {
380 if ( GetEntry() )
381 wxComboBox::SetEditable(editable);
382 }
383
384 #endif // wxUSE_BITMAPCOMBOBOX
385