X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/1e6feb95a79834836e88143b15d9f424ebe79621..f20ad12c585a0bca3b2de19fe5a4b6cb89de21c6:/src/gtk/listbox.cpp diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index 86679dd655..9cf8883c8e 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -90,11 +90,11 @@ static gint wxlistbox_idle_callback( gpointer gdata ) gdk_threads_enter(); gtk_idle_remove( data->m_tag ); - + data->m_listbox->SetFirstItem( data->m_item ); - + delete data; - + gdk_threads_leave(); return TRUE; @@ -219,7 +219,7 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis // eat return in all modes ret = TRUE; } - + #if wxUSE_CHECKLISTBOX if ((gdk_event->keyval == ' ') && (listbox->m_hasCheckBoxes) && (!ret)) { @@ -261,16 +261,31 @@ static void gtk_listitem_deselect_callback( GtkWidget *widget, wxListBox *listbo gtk_listitem_select_cb( widget, listbox, FALSE ); } -static void gtk_listitem_select_cb( GtkWidget *WXUNUSED(widget), wxListBox *listbox, bool is_selection ) +static void gtk_listitem_select_cb( GtkWidget *widget, wxListBox *listbox, bool is_selection ) { if (g_isIdle) wxapp_install_idle_handler(); if (!listbox->m_hasVMT) return; if (g_blockEventsOnDrag) return; + + if (listbox->m_blockEvent) return; wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); event.SetEventObject( listbox ); - event.SetExtraLong( (long) is_selection ); + +// MSW doesn't do that either +// event.SetExtraLong( (long) is_selection ); + + + if ((listbox->GetWindowStyleFlag() & wxLB_SINGLE) != 0) + { + int sel = listbox->GtkGetIndex( widget ); + + if (listbox->m_prevSelection != sel) + gtk_list_unselect_item( listbox->m_list, listbox->m_prevSelection ); + + listbox->m_prevSelection = sel; + } wxArrayInt aSelections; int n, count = listbox->GetSelections(aSelections); @@ -290,8 +305,9 @@ static void gtk_listitem_select_cb( GtkWidget *WXUNUSED(widget), wxListBox *list event.m_commandInt = n; - listbox->GetEventHandler()->AddPendingEvent( event ); -// listbox->GetEventHandler()->ProcessEvent( event ); +// No longer required with new code in wxLB_SINGLE +// listbox->GetEventHandler()->AddPendingEvent( event ); + listbox->GetEventHandler()->ProcessEvent( event ); } //----------------------------------------------------------------------------- @@ -320,6 +336,9 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, { m_needParent = TRUE; m_acceptsFocus = TRUE; + m_isListBox = TRUE; + m_prevSelection = 0; // or -1 ?? + m_blockEvent = FALSE; if (!PreCreation( parent, pos, size ) || !CreateBase( parent, id, pos, size, style, validator, name )) @@ -355,7 +374,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, { // if style was 0 set single mode m_windowStyle |= wxLB_SINGLE; - mode = GTK_SELECTION_BROWSE; + mode = GTK_SELECTION_MULTIPLE; } gtk_list_set_selection_mode( GTK_LIST(m_list), mode ); @@ -374,8 +393,6 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, gtk_widget_show( GTK_WIDGET(m_list) ); - SetBestSize( size ); - if ( style & wxLB_SORT ) { // this will change DoAppend() behaviour @@ -392,6 +409,10 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, DoAppend(choices[i]); } + // call it after appending the strings to the listbox, otherwise it doesn't + // work correctly + SetBestSize( size ); + m_parent->DoAddChild( this ); PostCreation(); @@ -410,7 +431,7 @@ wxListBox::~wxListBox() m_hasVMT = FALSE; Clear(); - + if (m_strings) delete m_strings; } @@ -441,7 +462,7 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos) for (size_t n = 0; n < nItems; n++) { index = m_strings->Add( items[n] ); - + if (index != GetCount()) { GtkAddItem( items[n], index ); @@ -535,7 +556,7 @@ void wxListBox::GtkAddItem( const wxString &item, int pos ) gtk_signal_connect( GTK_OBJECT(list_item), "select", GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this ); - if (HasFlag(wxLB_MULTIPLE)) + if (HasFlag(wxLB_MULTIPLE) || HasFlag(wxLB_EXTENDED)) gtk_signal_connect( GTK_OBJECT(list_item), "deselect", GTK_SIGNAL_FUNC(gtk_listitem_deselect_callback), (gpointer)this ); @@ -647,7 +668,13 @@ void wxListBox::Clear() { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); - gtk_list_clear_items( m_list, 0, Number() ); + gtk_list_clear_items( m_list, 0, GetCount() ); + + if ( GTK_LIST(m_list)->last_focus_child != NULL ) + { + // This should be NULL, I think. + GTK_LIST(m_list)->last_focus_child = NULL; + } if ( HasClientObjectData() ) { @@ -841,14 +868,19 @@ void wxListBox::SetSelection( int n, bool select ) { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); - GtkDisableEvents(); + m_blockEvent = TRUE; if (select) + { + if ((m_windowStyle & wxLB_SINGLE) != 0) + gtk_list_unselect_item( m_list, m_prevSelection ); gtk_list_select_item( m_list, n ); + m_prevSelection = n; + } else gtk_list_unselect_item( m_list, n ); - GtkEnableEvents(); + m_blockEvent = FALSE; } void wxListBox::DoSetFirstItem( int n ) @@ -857,18 +889,18 @@ void wxListBox::DoSetFirstItem( int n ) if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_list)) return; - - // terribly efficient + + // terribly efficient const gchar *vadjustment_key = "gtk-vadjustment"; guint vadjustment_key_id = g_quark_from_static_string (vadjustment_key); - - GtkAdjustment *adjustment = + + GtkAdjustment *adjustment = (GtkAdjustment*) gtk_object_get_data_by_id (GTK_OBJECT (m_list), vadjustment_key_id); wxCHECK_RET( adjustment, wxT("invalid listbox code") ); GList *target = g_list_nth( m_list->children, n ); wxCHECK_RET( target, wxT("invalid listbox index") ); - + GtkWidget *item = GTK_WIDGET(target->data); wxCHECK_RET( item, wxT("invalid listbox code") ); @@ -878,7 +910,7 @@ void wxListBox::DoSetFirstItem( int n ) data->m_listbox = this; data->m_item = n; data->m_tag = gtk_idle_add_priority( 800, wxlistbox_idle_callback, (gpointer) data ); - + return; } @@ -920,38 +952,6 @@ void wxListBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) } #endif // wxUSE_TOOLTIPS -void wxListBox::GtkDisableEvents() -{ - GList *child = m_list->children; - while (child) - { - gtk_signal_disconnect_by_func( GTK_OBJECT(child->data), - GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this ); - - if (HasFlag(wxLB_MULTIPLE)) - gtk_signal_disconnect_by_func( GTK_OBJECT(child->data), - GTK_SIGNAL_FUNC(gtk_listitem_deselect_callback), (gpointer)this ); - - child = child->next; - } -} - -void wxListBox::GtkEnableEvents() -{ - GList *child = m_list->children; - while (child) - { - gtk_signal_connect( GTK_OBJECT(child->data), "select", - GTK_SIGNAL_FUNC(gtk_listitem_select_callback), (gpointer)this ); - - if (HasFlag(wxLB_MULTIPLE)) - gtk_signal_connect( GTK_OBJECT(child->data), "deselect", - GTK_SIGNAL_FUNC(gtk_listitem_deselect_callback), (gpointer)this ); - - child = child->next; - } -} - GtkWidget *wxListBox::GetConnectWidget() { return GTK_WIDGET(m_list); @@ -1034,7 +1034,30 @@ void wxListBox::OnInternalIdle() wxSize wxListBox::DoGetBestSize() const { - return wxSize(100, 110); + int lbWidth = 100; // some defaults + int lbHeight = 110; + int wLine; + + // Find the widest line + for(int i = 0; i < GetCount(); i++) { + wxString str(GetString(i)); + GetTextExtent(str, &wLine, NULL); + lbWidth = wxMax(lbWidth, wLine); + } + + // Add room for the scrollbar + lbWidth += wxSystemSettings::GetSystemMetric(wxSYS_VSCROLL_X); + + // And just a bit more + int cx, cy; + GetTextExtent("X", &cx, &cy); + lbWidth += 3 * cx; + + // don't make the listbox too tall (limit height to around 10 items) but don't + // make it too small neither + lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10); + + return wxSize(lbWidth, lbHeight); } #endif