~registry/dolphin-emu/triforce

« back to all changes in this revision

Viewing changes to Externals/wxWidgets3/src/gtk/combobox.cpp

  • Committer: Sérgio Benjamim
  • Date: 2015-02-13 05:54:40 UTC
  • Revision ID: sergio_br2@yahoo.com.br-20150213055440-ey2rt3sjpy27km78
Dolphin Triforce branch from code.google, commit b957980 (4.0-315).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/////////////////////////////////////////////////////////////////////////////
 
2
// Name:        src/gtk/combobox.cpp
 
3
// Purpose:
 
4
// Author:      Robert Roebling
 
5
// Copyright:   (c) 1998 Robert Roebling
 
6
// Licence:     wxWindows licence
 
7
/////////////////////////////////////////////////////////////////////////////
 
8
 
 
9
// For compilers that support precompilation, includes "wx.h".
 
10
#include "wx/wxprec.h"
 
11
 
 
12
#if wxUSE_COMBOBOX
 
13
 
 
14
#include "wx/combobox.h"
 
15
 
 
16
#ifndef WX_PRECOMP
 
17
    #include "wx/intl.h"
 
18
    #include "wx/settings.h"
 
19
    #include "wx/textctrl.h"    // for wxEVT_TEXT
 
20
    #include "wx/arrstr.h"
 
21
#endif
 
22
 
 
23
#include <gtk/gtk.h>
 
24
#include "wx/gtk/private.h"
 
25
#include "wx/gtk/private/gtk2-compat.h"
 
26
 
 
27
// ----------------------------------------------------------------------------
 
28
// GTK callbacks
 
29
// ----------------------------------------------------------------------------
 
30
 
 
31
extern "C" {
 
32
static void
 
33
gtkcombobox_text_changed_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
 
34
{
 
35
    wxCommandEvent event( wxEVT_TEXT, combo->GetId() );
 
36
    event.SetString( combo->GetValue() );
 
37
    event.SetEventObject( combo );
 
38
    combo->HandleWindowEvent( event );
 
39
}
 
40
 
 
41
static void
 
42
gtkcombobox_changed_callback( GtkWidget *WXUNUSED(widget), wxComboBox *combo )
 
43
{
 
44
    combo->SendSelectionChangedEvent(wxEVT_COMBOBOX);
 
45
}
 
46
 
 
47
static void
 
48
gtkcombobox_popupshown_callback(GObject *WXUNUSED(gobject),
 
49
                                GParamSpec *WXUNUSED(param_spec),
 
50
                                wxComboBox *combo)
 
51
{
 
52
    gboolean isShown;
 
53
    g_object_get( combo->m_widget, "popup-shown", &isShown, NULL );
 
54
    wxCommandEvent event( isShown ? wxEVT_COMBOBOX_DROPDOWN
 
55
                                  : wxEVT_COMBOBOX_CLOSEUP,
 
56
                          combo->GetId() );
 
57
    event.SetEventObject( combo );
 
58
    combo->HandleWindowEvent( event );
 
59
}
 
60
 
 
61
}
 
62
 
 
63
//-----------------------------------------------------------------------------
 
64
// wxComboBox
 
65
//-----------------------------------------------------------------------------
 
66
 
 
67
BEGIN_EVENT_TABLE(wxComboBox, wxChoice)
 
68
    EVT_CHAR(wxComboBox::OnChar)
 
69
 
 
70
    EVT_MENU(wxID_CUT, wxComboBox::OnCut)
 
71
    EVT_MENU(wxID_COPY, wxComboBox::OnCopy)
 
72
    EVT_MENU(wxID_PASTE, wxComboBox::OnPaste)
 
73
    EVT_MENU(wxID_UNDO, wxComboBox::OnUndo)
 
74
    EVT_MENU(wxID_REDO, wxComboBox::OnRedo)
 
75
    EVT_MENU(wxID_CLEAR, wxComboBox::OnDelete)
 
76
    EVT_MENU(wxID_SELECTALL, wxComboBox::OnSelectAll)
 
77
 
 
78
    EVT_UPDATE_UI(wxID_CUT, wxComboBox::OnUpdateCut)
 
79
    EVT_UPDATE_UI(wxID_COPY, wxComboBox::OnUpdateCopy)
 
80
    EVT_UPDATE_UI(wxID_PASTE, wxComboBox::OnUpdatePaste)
 
81
    EVT_UPDATE_UI(wxID_UNDO, wxComboBox::OnUpdateUndo)
 
82
    EVT_UPDATE_UI(wxID_REDO, wxComboBox::OnUpdateRedo)
 
83
    EVT_UPDATE_UI(wxID_CLEAR, wxComboBox::OnUpdateDelete)
 
84
    EVT_UPDATE_UI(wxID_SELECTALL, wxComboBox::OnUpdateSelectAll)
 
85
END_EVENT_TABLE()
 
86
 
 
87
wxComboBox::~wxComboBox()
 
88
{
 
89
    if (m_entry)
 
90
        GTKDisconnect(m_entry);
 
91
}
 
92
 
 
93
void wxComboBox::Init()
 
94
{
 
95
    m_entry = NULL;
 
96
}
 
97
 
 
98
bool wxComboBox::Create( wxWindow *parent, wxWindowID id,
 
99
                         const wxString& value,
 
100
                         const wxPoint& pos, const wxSize& size,
 
101
                         const wxArrayString& choices,
 
102
                         long style, const wxValidator& validator,
 
103
                         const wxString& name )
 
104
{
 
105
    wxCArrayString chs(choices);
 
106
 
 
107
    return Create( parent, id, value, pos, size, chs.GetCount(),
 
108
                   chs.GetStrings(), style, validator, name );
 
109
}
 
110
 
 
111
bool wxComboBox::Create( wxWindow *parent, wxWindowID id, const wxString& value,
 
112
                         const wxPoint& pos, const wxSize& size,
 
113
                         int n, const wxString choices[],
 
114
                         long style, const wxValidator& validator,
 
115
                         const wxString& name )
 
116
{
 
117
    if (!PreCreation( parent, pos, size ) ||
 
118
        !CreateBase( parent, id, pos, size, style, validator, name ))
 
119
    {
 
120
        wxFAIL_MSG( wxT("wxComboBox creation failed") );
 
121
        return false;
 
122
    }
 
123
 
 
124
    if (HasFlag(wxCB_SORT))
 
125
        m_strings = new wxGtkCollatedArrayString();
 
126
 
 
127
    GTKCreateComboBoxWidget();
 
128
 
 
129
    if (HasFlag(wxBORDER_NONE))
 
130
    {
 
131
        // Doesn't seem to work
 
132
        // g_object_set (m_widget, "has-frame", FALSE, NULL);
 
133
    }
 
134
 
 
135
    GtkEntry * const entry = GetEntry();
 
136
 
 
137
    if ( entry )
 
138
    {
 
139
        // Set it up to trigger default item on enter key press
 
140
        gtk_entry_set_activates_default( entry,
 
141
                                         !HasFlag(wxTE_PROCESS_ENTER) );
 
142
 
 
143
        gtk_editable_set_editable(GTK_EDITABLE(entry), true);
 
144
    }
 
145
 
 
146
    Append(n, choices);
 
147
 
 
148
    m_parent->DoAddChild( this );
 
149
 
 
150
    if ( entry )
 
151
        m_focusWidget = GTK_WIDGET( entry );
 
152
 
 
153
    PostCreation(size);
 
154
 
 
155
    if ( entry )
 
156
    {
 
157
        if (style & wxCB_READONLY)
 
158
        {
 
159
            // this will assert and do nothing if the value is not in our list
 
160
            // of strings which is the desired behaviour (for consistency with
 
161
            // wxMSW and also because it doesn't make sense to have a string
 
162
            // which is not a possible choice in a read-only combobox)
 
163
            SetStringSelection(value);
 
164
            gtk_editable_set_editable(GTK_EDITABLE(entry), false);
 
165
        }
 
166
        else // editable combobox
 
167
        {
 
168
            // any value is accepted, even if it's not in our list
 
169
            gtk_entry_set_text( entry, wxGTK_CONV(value) );
 
170
        }
 
171
 
 
172
        g_signal_connect_after (entry, "changed",
 
173
                                G_CALLBACK (gtkcombobox_text_changed_callback), this);
 
174
 
 
175
        GTKConnectInsertTextSignal(entry);
 
176
        GTKConnectClipboardSignals(GTK_WIDGET(entry));
 
177
    }
 
178
 
 
179
    g_signal_connect_after (m_widget, "changed",
 
180
                        G_CALLBACK (gtkcombobox_changed_callback), this);
 
181
 
 
182
#ifndef __WXGTK3__
 
183
    if ( !gtk_check_version(2,10,0) )
 
184
#endif
 
185
    {
 
186
        g_signal_connect (m_widget, "notify::popup-shown",
 
187
                          G_CALLBACK (gtkcombobox_popupshown_callback), this);
 
188
    }
 
189
 
 
190
    return true;
 
191
}
 
192
 
 
193
void wxComboBox::GTKCreateComboBoxWidget()
 
194
{
 
195
#ifdef __WXGTK3__
 
196
    m_widget = gtk_combo_box_text_new_with_entry();
 
197
#else
 
198
    m_widget = gtk_combo_box_entry_new_text();
 
199
#endif
 
200
    g_object_ref(m_widget);
 
201
 
 
202
    m_entry = GTK_ENTRY(gtk_bin_get_child(GTK_BIN(m_widget)));
 
203
}
 
204
 
 
205
GtkEditable *wxComboBox::GetEditable() const
 
206
{
 
207
    return GTK_EDITABLE(gtk_bin_get_child(GTK_BIN(m_widget)));
 
208
}
 
209
 
 
210
void wxComboBox::OnChar( wxKeyEvent &event )
 
211
{
 
212
    switch ( event.GetKeyCode() )
 
213
    {
 
214
        case WXK_RETURN:
 
215
            if ( HasFlag(wxTE_PROCESS_ENTER) && GetEntry() )
 
216
            {
 
217
                // GTK automatically selects an item if its in the list
 
218
                wxCommandEvent eventEnter(wxEVT_TEXT_ENTER, GetId());
 
219
                eventEnter.SetString( GetValue() );
 
220
                eventEnter.SetInt( GetSelection() );
 
221
                eventEnter.SetEventObject( this );
 
222
 
 
223
                if ( HandleWindowEvent(eventEnter) )
 
224
                {
 
225
                    // Catch GTK event so that GTK doesn't open the drop
 
226
                    // down list upon RETURN.
 
227
                    return;
 
228
                }
 
229
            }
 
230
            break;
 
231
    }
 
232
 
 
233
    event.Skip();
 
234
}
 
235
 
 
236
void wxComboBox::EnableTextChangedEvents(bool enable)
 
237
{
 
238
    if ( !GetEntry() )
 
239
        return;
 
240
 
 
241
    if ( enable )
 
242
    {
 
243
        g_signal_handlers_unblock_by_func(gtk_bin_get_child(GTK_BIN(m_widget)),
 
244
            (gpointer)gtkcombobox_text_changed_callback, this);
 
245
    }
 
246
    else // disable
 
247
    {
 
248
        g_signal_handlers_block_by_func(gtk_bin_get_child(GTK_BIN(m_widget)),
 
249
            (gpointer)gtkcombobox_text_changed_callback, this);
 
250
    }
 
251
}
 
252
 
 
253
void wxComboBox::GTKDisableEvents()
 
254
{
 
255
    EnableTextChangedEvents(false);
 
256
 
 
257
    g_signal_handlers_block_by_func(m_widget,
 
258
        (gpointer)gtkcombobox_changed_callback, this);
 
259
    g_signal_handlers_block_by_func(m_widget,
 
260
        (gpointer)gtkcombobox_popupshown_callback, this);
 
261
}
 
262
 
 
263
void wxComboBox::GTKEnableEvents()
 
264
{
 
265
    EnableTextChangedEvents(true);
 
266
 
 
267
    g_signal_handlers_unblock_by_func(m_widget,
 
268
        (gpointer)gtkcombobox_changed_callback, this);
 
269
    g_signal_handlers_unblock_by_func(m_widget,
 
270
        (gpointer)gtkcombobox_popupshown_callback, this);
 
271
}
 
272
 
 
273
GtkWidget* wxComboBox::GetConnectWidget()
 
274
{
 
275
    return GTK_WIDGET( GetEntry() );
 
276
}
 
277
 
 
278
GdkWindow* wxComboBox::GTKGetWindow(wxArrayGdkWindows& /* windows */) const
 
279
{
 
280
#ifdef __WXGTK3__
 
281
    // no access to internal GdkWindows
 
282
    return NULL;
 
283
#else
 
284
    return gtk_entry_get_text_window(GetEntry());
 
285
#endif
 
286
}
 
287
 
 
288
// static
 
289
wxVisualAttributes
 
290
wxComboBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant))
 
291
{
 
292
#ifdef __WXGTK3__
 
293
    return GetDefaultAttributesFromGTKWidget(gtk_combo_box_new_with_entry(), true);
 
294
#else
 
295
    return GetDefaultAttributesFromGTKWidget(gtk_combo_box_entry_new(), true);
 
296
#endif
 
297
}
 
298
 
 
299
void wxComboBox::SetValue(const wxString& value)
 
300
{
 
301
    if ( HasFlag(wxCB_READONLY) )
 
302
        SetStringSelection(value);
 
303
    else
 
304
        wxTextEntry::SetValue(value);
 
305
}
 
306
 
 
307
void wxComboBox::SetString(unsigned int n, const wxString& text)
 
308
{
 
309
    wxChoice::SetString(n, text);
 
310
 
 
311
    if ( static_cast<int>(n) == GetSelection() )
 
312
    {
 
313
        // We also need to update the currently shown text, for consistency
 
314
        // with wxMSW and also because it makes sense as leaving the old string
 
315
        // in the text but not in the list would be confusing to the user.
 
316
        SetValue(text);
 
317
 
 
318
        // And we need to keep the selection unchanged, modifying the item is
 
319
        // not supposed to deselect it.
 
320
        SetSelection(n);
 
321
    }
 
322
}
 
323
 
 
324
// ----------------------------------------------------------------------------
 
325
// standard event handling
 
326
// ----------------------------------------------------------------------------
 
327
 
 
328
void wxComboBox::OnCut(wxCommandEvent& WXUNUSED(event))
 
329
{
 
330
    Cut();
 
331
}
 
332
 
 
333
void wxComboBox::OnCopy(wxCommandEvent& WXUNUSED(event))
 
334
{
 
335
    Copy();
 
336
}
 
337
 
 
338
void wxComboBox::OnPaste(wxCommandEvent& WXUNUSED(event))
 
339
{
 
340
    Paste();
 
341
}
 
342
 
 
343
void wxComboBox::OnUndo(wxCommandEvent& WXUNUSED(event))
 
344
{
 
345
    Undo();
 
346
}
 
347
 
 
348
void wxComboBox::OnRedo(wxCommandEvent& WXUNUSED(event))
 
349
{
 
350
    Redo();
 
351
}
 
352
 
 
353
void wxComboBox::OnDelete(wxCommandEvent& WXUNUSED(event))
 
354
{
 
355
    RemoveSelection();
 
356
}
 
357
 
 
358
void wxComboBox::OnSelectAll(wxCommandEvent& WXUNUSED(event))
 
359
{
 
360
    SelectAll();
 
361
}
 
362
 
 
363
void wxComboBox::OnUpdateCut(wxUpdateUIEvent& event)
 
364
{
 
365
    event.Enable( CanCut() );
 
366
}
 
367
 
 
368
void wxComboBox::OnUpdateCopy(wxUpdateUIEvent& event)
 
369
{
 
370
    event.Enable( CanCopy() );
 
371
}
 
372
 
 
373
void wxComboBox::OnUpdatePaste(wxUpdateUIEvent& event)
 
374
{
 
375
    event.Enable( CanPaste() );
 
376
}
 
377
 
 
378
void wxComboBox::OnUpdateUndo(wxUpdateUIEvent& event)
 
379
{
 
380
    event.Enable( CanUndo() );
 
381
}
 
382
 
 
383
void wxComboBox::OnUpdateRedo(wxUpdateUIEvent& event)
 
384
{
 
385
    event.Enable( CanRedo() );
 
386
}
 
387
 
 
388
void wxComboBox::OnUpdateDelete(wxUpdateUIEvent& event)
 
389
{
 
390
    event.Enable(HasSelection() && IsEditable()) ;
 
391
}
 
392
 
 
393
void wxComboBox::OnUpdateSelectAll(wxUpdateUIEvent& event)
 
394
{
 
395
    event.Enable(!wxTextEntry::IsEmpty());
 
396
}
 
397
 
 
398
void wxComboBox::Popup()
 
399
{
 
400
     gtk_combo_box_popup( GTK_COMBO_BOX(m_widget) );
 
401
}
 
402
 
 
403
void wxComboBox::Dismiss()
 
404
{
 
405
    gtk_combo_box_popdown( GTK_COMBO_BOX(m_widget) );
 
406
}
 
407
 
 
408
wxSize wxComboBox::DoGetSizeFromTextSize(int xlen, int ylen) const
 
409
{
 
410
    wxSize tsize( wxChoice::DoGetSizeFromTextSize(xlen, ylen) );
 
411
 
 
412
    GtkEntry* entry = GetEntry();
 
413
    if (entry)
 
414
    {
 
415
        // Add the margins we have previously set, but only the horizontal border
 
416
        // as vertical one has been taken account in the previous call.
 
417
        // Also get other GTK+ margins.
 
418
        tsize.IncBy(GTKGetEntryMargins(entry).x, 0);
 
419
    }
 
420
 
 
421
    return tsize;
 
422
}
 
423
 
 
424
#endif // wxUSE_COMBOBOX