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