]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/bmpcbox.cpp
Fix crash in wxDC::GetMultiLineTextExtent() after last commit.
[wxWidgets.git] / src / gtk / bmpcbox.cpp
CommitLineData
e78c1d78 1/////////////////////////////////////////////////////////////////////////////
80fdcdb9 2// Name: src/gtk/bmpcbox.cpp
e78c1d78
RR
3// Purpose: wxBitmapComboBox
4// Author: Jaakko Salli
5// Created: 2008-05-19
2903e699 6// RCS-ID: $Id$
e78c1d78
RR
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
9dc44eff 33#include <gtk/gtk.h>
e78c1d78
RR
34#include "wx/gtk/private.h"
35
e78c1d78
RR
36// ============================================================================
37// implementation
38// ============================================================================
39
40
41IMPLEMENT_DYNAMIC_CLASS(wxBitmapComboBox, wxComboBox)
42
43
44// ----------------------------------------------------------------------------
45// wxBitmapComboBox creation
46// ----------------------------------------------------------------------------
47
48void wxBitmapComboBox::Init()
49{
50 m_bitmapCellIndex = 0;
51 m_stringCellIndex = 1;
60b71826 52 m_bitmapSize = wxSize(-1, -1);
e78c1d78
RR
53}
54
55wxBitmapComboBox::wxBitmapComboBox(wxWindow *parent,
56 wxWindowID id,
57 const wxString& value,
58 const wxPoint& pos,
59 const wxSize& size,
60 const wxArrayString& choices,
61 long style,
62 const wxValidator& validator,
63 const wxString& name)
64 : wxComboBox(),
65 wxBitmapComboBoxBase()
66{
67 Init();
68
69 Create(parent,id,value,pos,size,choices,style,validator,name);
70}
71
72bool wxBitmapComboBox::Create(wxWindow *parent,
73 wxWindowID id,
74 const wxString& value,
75 const wxPoint& pos,
76 const wxSize& size,
77 const wxArrayString& choices,
78 long style,
79 const wxValidator& validator,
80 const wxString& name)
81{
82 wxCArrayString chs(choices);
83 return Create(parent, id, value, pos, size, chs.GetCount(),
84 chs.GetStrings(), style, validator, name);
85}
86
87bool wxBitmapComboBox::Create(wxWindow *parent,
88 wxWindowID id,
89 const wxString& value,
90 const wxPoint& pos,
91 const wxSize& size,
92 int n,
93 const wxString choices[],
94 long style,
95 const wxValidator& validator,
96 const wxString& name)
97{
98 if ( !wxComboBox::Create(parent, id, value, pos, size,
99 n, choices, style, validator, name) )
100 return false;
101
102 // Select 'value' in entry-less mode
103 if ( !GetEntry() )
104 {
7d1214cd
PC
105 int i = FindString(value);
106 if (i != wxNOT_FOUND)
107 SetSelection(i);
e78c1d78
RR
108 }
109
110 return true;
111}
112
113void wxBitmapComboBox::GTKCreateComboBoxWidget()
114{
115 GtkListStore *store;
116
117 store = gtk_list_store_new( 2, G_TYPE_OBJECT, G_TYPE_STRING );
118
119 if ( HasFlag(wxCB_READONLY) )
120 {
121 m_widget = gtk_combo_box_new_with_model( GTK_TREE_MODEL(store) );
122 }
123 else
124 {
9dc44eff
PC
125#ifdef __WXGTK3__
126 m_widget = gtk_combo_box_new_with_model_and_entry(GTK_TREE_MODEL(store));
0e1e0ea9 127 gtk_combo_box_set_entry_text_column(GTK_COMBO_BOX(m_widget), m_stringCellIndex);
9dc44eff 128#else
e78c1d78 129 m_widget = gtk_combo_box_entry_new_with_model( GTK_TREE_MODEL(store), m_stringCellIndex );
9dc44eff 130#endif
385e8575
PC
131 m_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(m_widget)));
132 gtk_editable_set_editable(GTK_EDITABLE(m_entry), true);
e78c1d78 133 }
9ff9d30c 134 g_object_ref(m_widget);
e78c1d78
RR
135
136 // This must be called as gtk_combo_box_entry_new_with_model adds
137 // automatically adds one text column.
60b71826 138 gtk_cell_layout_clear( GTK_CELL_LAYOUT(m_widget) );
e78c1d78
RR
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
153wxBitmapComboBox::~wxBitmapComboBox()
154{
155}
156
157GtkWidget* wxBitmapComboBox::GetConnectWidget()
158{
159 if ( GetEntry() )
160 return wxComboBox::GetConnectWidget();
161
162 return wxChoice::GetConnectWidget();
163}
164
165GdkWindow *wxBitmapComboBox::GTKGetWindow(wxArrayGdkWindows& windows) const
166{
167 if ( GetEntry() )
168 return wxComboBox::GTKGetWindow(windows);
60b71826 169
e78c1d78
RR
170 return wxChoice::GTKGetWindow(windows);
171}
172
c90e98dc
JS
173wxSize 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
e78c1d78
RR
186// ----------------------------------------------------------------------------
187// Item manipulation
188// ----------------------------------------------------------------------------
189
190void wxBitmapComboBox::SetItemBitmap(unsigned int n, const wxBitmap& bitmap)
191{
192 if ( bitmap.IsOk() )
193 {
60b71826 194 if ( m_bitmapSize.x < 0 )
e78c1d78
RR
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 = { 0, };
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
216wxBitmap 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 = { 0, };
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 );
54195d23 233 bitmap = wxBitmap(pixbuf);
e78c1d78
RR
234 }
235 g_value_unset( &value );
236 }
237
238 return bitmap;
239}
240
241int 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
249int 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
258int 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
267int 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
277int 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
90fae9d2
JS
286int 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
e78c1d78
RR
295void 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 = { 0, };
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
315void wxBitmapComboBox::WriteText(const wxString& value)
316{
317 if ( GetEntry() )
318 wxComboBox::WriteText(value);
268203fb
JS
319 else
320 SetStringSelection(value);
e78c1d78
RR
321}
322
323wxString wxBitmapComboBox::GetValue() const
324{
325 if ( GetEntry() )
326 return wxComboBox::GetValue();
327
328 return GetStringSelection();
329}
330
331void wxBitmapComboBox::Remove(long from, long to)
332{
333 if ( GetEntry() )
334 wxComboBox::Remove(from, to);
335}
336
337void wxBitmapComboBox::SetInsertionPoint(long pos)
338{
339 if ( GetEntry() )
340 wxComboBox::SetInsertionPoint(pos);
341}
342
343long wxBitmapComboBox::GetInsertionPoint() const
344{
345 if ( GetEntry() )
346 return wxComboBox::GetInsertionPoint();
347
348 return 0;
349 }
350long wxBitmapComboBox::GetLastPosition() const
351{
352 if ( GetEntry() )
353 return wxComboBox::GetLastPosition();
354
355 return 0;
356 }
357
358void wxBitmapComboBox::SetSelection(long from, long to)
359{
360 if ( GetEntry() )
361 wxComboBox::SetSelection(from, to);
362}
363
364void wxBitmapComboBox::GetSelection(long *from, long *to) const
365{
366 if ( GetEntry() )
367 wxComboBox::GetSelection(from, to);
368}
369
370bool wxBitmapComboBox::IsEditable() const
371{
372 if ( GetEntry() )
373 return wxTextEntry::IsEditable();
374
375 return false;
376}
377
378void wxBitmapComboBox::SetEditable(bool editable)
379{
380 if ( GetEntry() )
381 wxComboBox::SetEditable(editable);
382}
383
384#endif // wxUSE_BITMAPCOMBOBOX