X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/de6185e212ebc37ff11ff70278e3c4f68419b097..f363cee882672e147340240cf0bb194a68e37833:/src/gtk1/listbox.cpp diff --git a/src/gtk1/listbox.cpp b/src/gtk1/listbox.cpp index ab51f39ea5..1220748fa7 100644 --- a/src/gtk1/listbox.cpp +++ b/src/gtk1/listbox.cpp @@ -2,7 +2,6 @@ // Name: src/gtk1/listbox.cpp // Purpose: // Author: Robert Roebling -// Id: $Id$ // Copyright: (c) 1998 Robert Roebling // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// @@ -18,11 +17,11 @@ #include "wx/dynarray.h" #include "wx/intl.h" #include "wx/utils.h" + #include "wx/settings.h" + #include "wx/checklst.h" + #include "wx/arrstr.h" #endif -#include "wx/arrstr.h" -#include "wx/checklst.h" -#include "wx/settings.h" #include "wx/gtk1/private.h" #if wxUSE_TOOLTIPS @@ -93,9 +92,9 @@ static gint wxlistbox_idle_callback( gpointer gdata ) //----------------------------------------------------------------------------- extern "C" { -static gint gtk_listitem_focus_in_callback( GtkWidget *widget, - GdkEvent *WXUNUSED(event), - wxWindow *win ) +static gint gtk_listitem_focus_in_callback( GtkWidget *WXUNUSED(widget), + GdkEvent *WXUNUSED(event), + wxWindow *win ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -110,12 +109,12 @@ static gint gtk_listitem_focus_in_callback( GtkWidget *widget, win->m_hasFocus = true; wxChildFocusEvent eventChildFocus(win); - (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); + (void)win->HandleWindowEvent(eventChildFocus); wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); eventFocus.SetEventObject(win); - (void)win->GetEventHandler()->ProcessEvent(eventFocus); + (void)win->HandleWindowEvent(eventFocus); } return FALSE; @@ -127,12 +126,14 @@ static gint gtk_listitem_focus_in_callback( GtkWidget *widget, //----------------------------------------------------------------------------- extern "C" { -static gint gtk_listitem_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win ) +static gint gtk_listitem_focus_out_callback( GtkWidget *WXUNUSED(widget), + GdkEventFocus *WXUNUSED(gdk_event), + wxWindowGTK *win ) { if (g_isIdle) wxapp_install_idle_handler(); - g_focusWindow = (wxWindowGTK *)NULL; + g_focusWindow = NULL; // don't send the window a kill focus event if it thinks that it doesn't // have focus already @@ -147,7 +148,7 @@ static gint gtk_listitem_focus_out_callback( GtkWidget *widget, GdkEventFocus *g // process it too as otherwise bad things happen, especially in GTK2 // where the text control simply aborts the program if it doesn't get // the matching focus out event - (void)win->GetEventHandler()->ProcessEvent( event ); + (void)win->HandleWindowEvent( event ); } return FALSE; @@ -158,7 +159,7 @@ static gint gtk_listitem_focus_out_callback( GtkWidget *widget, GdkEventFocus *g // "button_release_event" //----------------------------------------------------------------------------- -/* we would normally emit a wxEVT_COMMAND_LISTBOX_DOUBLECLICKED event once +/* we would normally emit a wxEVT_LISTBOX_DCLICK event once a GDK_2BUTTON_PRESS occurs, but this has the particular problem of the listbox keeping the focus until it receives a GDK_BUTTON_RELEASE event. this can lead to race conditions so that we emit the dclick event @@ -179,7 +180,7 @@ gtk_listbox_button_release_callback( GtkWidget * WXUNUSED(widget), if (!g_hasDoubleClicked) return FALSE; - wxCommandEvent event( wxEVT_COMMAND_LISTBOX_DOUBLECLICKED, listbox->GetId() ); + wxCommandEvent event( wxEVT_LISTBOX_DCLICK, listbox->GetId() ); event.SetEventObject( listbox ); wxArrayInt aSelections; @@ -200,7 +201,7 @@ gtk_listbox_button_release_callback( GtkWidget * WXUNUSED(widget), event.SetInt(n); - listbox->GetEventHandler()->ProcessEvent( event ); + listbox->HandleWindowEvent( event ); return FALSE; } @@ -232,10 +233,10 @@ gtk_listbox_button_press_callback( GtkWidget *widget, clb->Check( sel, !clb->IsChecked(sel) ); - wxCommandEvent event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, listbox->GetId() ); + wxCommandEvent event( wxEVT_CHECKLISTBOX, listbox->GetId() ); event.SetEventObject( listbox ); event.SetInt( sel ); - listbox->GetEventHandler()->ProcessEvent( event ); + listbox->HandleWindowEvent( event ); } #endif // wxUSE_CHECKLISTBOX @@ -255,7 +256,7 @@ gtk_listbox_button_press_callback( GtkWidget *widget, return false; } - /* emit wxEVT_COMMAND_LISTBOX_DOUBLECLICKED later */ + /* emit wxEVT_LISTBOX_DCLICK later */ g_hasDoubleClicked = (gdk_event->type == GDK_2BUTTON_PRESS); return FALSE; @@ -286,7 +287,7 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); new_event.SetCurrentFocus( listbox ); - ret = listbox->GetEventHandler()->ProcessEvent( new_event ); + ret = listbox->HandleWindowEvent( new_event ); } if ((gdk_event->keyval == GDK_Return) && (!ret)) @@ -304,10 +305,10 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis clb->Check( sel, !clb->IsChecked(sel) ); - wxCommandEvent new_event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, listbox->GetId() ); + wxCommandEvent new_event( wxEVT_CHECKLISTBOX, listbox->GetId() ); new_event.SetEventObject( listbox ); new_event.SetInt( sel ); - ret = listbox->GetEventHandler()->ProcessEvent( new_event ); + ret = listbox->HandleWindowEvent( new_event ); } #endif // wxUSE_CHECKLISTBOX @@ -327,7 +328,7 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis else gtk_list_select_item( listbox->m_list, sel ); - wxCommandEvent new_event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); + wxCommandEvent new_event(wxEVT_LISTBOX, listbox->GetId() ); new_event.SetEventObject( listbox ); wxArrayInt aSelections; int n, count = listbox->GetSelections(aSelections); @@ -345,7 +346,7 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis n = -1; } new_event.SetInt(n); - listbox->GetEventHandler()->ProcessEvent( new_event ); + listbox->HandleWindowEvent( new_event ); } } @@ -374,7 +375,7 @@ static void gtk_listitem_select_cb( GtkWidget *widget, if (listbox->m_blockEvent) return; - wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); + wxCommandEvent event(wxEVT_LISTBOX, listbox->GetId() ); event.SetEventObject( listbox ); // indicate whether this is a selection or a deselection @@ -410,7 +411,7 @@ static void gtk_listitem_select_cb( GtkWidget *widget, // No longer required with new code in wxLB_SINGLE // listbox->GetEventHandler()->AddPendingEvent( event ); - listbox->GetEventHandler()->ProcessEvent( event ); + listbox->HandleWindowEvent( event ); } extern "C" { @@ -433,7 +434,7 @@ static void gtk_listitem_deselect_callback( GtkWidget *widget, wxListBox *listbo extern "C" { static gint -gtk_listbox_realized_callback( GtkWidget *m_widget, wxListBox *win ) +gtk_listbox_realized_callback( GtkWidget *WXUNUSED(widget), wxListBox *win ) { if (g_isIdle) wxapp_install_idle_handler(); @@ -450,15 +451,13 @@ gtk_listbox_realized_callback( GtkWidget *m_widget, wxListBox *win ) // wxListBox //----------------------------------------------------------------------------- -IMPLEMENT_DYNAMIC_CLASS(wxListBox,wxControl) - // ---------------------------------------------------------------------------- // construction // ---------------------------------------------------------------------------- wxListBox::wxListBox() { - m_list = (GtkList *) NULL; + m_list = NULL; #if wxUSE_CHECKLISTBOX m_hasCheckBoxes = false; #endif // wxUSE_CHECKLISTBOX @@ -494,7 +493,7 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, return false; } - m_widget = gtk_scrolled_window_new( (GtkAdjustment*) NULL, (GtkAdjustment*) NULL ); + m_widget = gtk_scrolled_window_new( NULL, NULL ); if (style & wxLB_ALWAYS_SB) { gtk_scrolled_window_set_policy( GTK_SCROLLED_WINDOW(m_widget), @@ -541,24 +540,20 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, if ( style & wxLB_SORT ) { - // this will change DoAppend() behaviour + // this will change Append() behaviour m_strings = new wxSortedArrayString; } else { - m_strings = (wxSortedArrayString *)NULL; + m_strings = NULL; } - for (int i = 0; i < n; i++) - { - // add one by one - DoAppend(choices[i]); - } + Append(n, choices); m_parent->DoAddChild( this ); PostCreation(size); - SetBestSize(size); // need this too because this is a wxControlWithItems + SetInitialSize(size); // need this too because this is a wxControlWithItems return true; } @@ -569,109 +564,51 @@ wxListBox::~wxListBox() Clear(); - if (m_strings) - delete m_strings; + delete m_strings; } // ---------------------------------------------------------------------------- // adding items // ---------------------------------------------------------------------------- -void wxListBox::DoInsertItems(const wxArrayString& items, unsigned int pos) +int wxListBox::DoInsertItems(const wxArrayStringsAdapter& items, + unsigned int pos, + void **clientData, + wxClientDataType type) { - wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); + wxCHECK_MSG( m_list != NULL, wxNOT_FOUND, wxT("invalid listbox") ); - // VZ: notice that InsertItems knows nothing about sorting, so calling it - // from outside (and not from our own Append) is likely to break - // everything + const unsigned count = GetCount(); + wxCHECK_MSG( pos <= count, wxNOT_FOUND, + wxT("invalid index in wxListBox::InsertItems") ); // code elsewhere supposes we have as many items in m_clientList as items // in the listbox - wxASSERT_MSG( m_clientList.GetCount() == GetCount(), - wxT("bug in client data management") ); + wxASSERT_MSG( m_clientList.GetCount() == count, + wxT("bug in client data management") ); InvalidateBestSize(); - GList *children = m_list->children; - unsigned int length = g_list_length(children); - - wxCHECK_RET( pos <= length, wxT("invalid index in wxListBox::InsertItems") ); + const unsigned numItems = items.GetCount(); - unsigned int nItems = items.GetCount(); - int index; - - if (m_strings) + for ( unsigned int n = 0; n < numItems; ++n, ++pos ) { - for (unsigned int n = 0; n < nItems; n++) - { - index = m_strings->Add( items[n] ); + const wxString& item = items[n]; - if (index != (int)GetCount()) - { - GtkAddItem( items[n], index ); - wxList::compatibility_iterator node = m_clientList.Item( index ); - m_clientList.Insert( node, (wxObject*) NULL ); - } - else - { - GtkAddItem( items[n] ); - m_clientList.Append( (wxObject*) NULL ); - } - } - } - else - { - if (pos == length) - { - for ( unsigned int n = 0; n < nItems; n++ ) - { - GtkAddItem( items[n] ); + const unsigned idx = m_strings ? m_strings->Add(item) + : pos; - m_clientList.Append((wxObject *)NULL); - } - } - else - { - wxList::compatibility_iterator node = m_clientList.Item( pos ); - for ( unsigned int n = 0; n < nItems; n++ ) - { - GtkAddItem( items[n], pos+n ); + GtkAddItem(item, idx == GetCount() ? (unsigned) -1 : idx); - m_clientList.Insert( node, (wxObject *)NULL ); - } - } + m_clientList.Insert(idx, NULL); + + AssignNewItemClientData(idx, clientData, n, type); } wxASSERT_MSG( m_clientList.GetCount() == GetCount(), wxT("bug in client data management") ); -} - -int wxListBox::DoAppend( const wxString& item ) -{ - InvalidateBestSize(); - - if (m_strings) - { - // need to determine the index - int index = m_strings->Add( item ); - // only if not at the end anyway - if (index != (int)GetCount()) - { - GtkAddItem( item, index ); - - wxList::compatibility_iterator node = m_clientList.Item( index ); - m_clientList.Insert( node, (wxObject *)NULL ); - - return index; - } - } - - GtkAddItem(item); - - m_clientList.Append((wxObject *)NULL); - - return GetCount() - 1; + return pos - 1; } void wxListBox::GtkAddItem( const wxString &item, int pos ) @@ -752,28 +689,11 @@ void wxListBox::GtkAddItem( const wxString &item, int pos ) } } -void wxListBox::DoSetItems( const wxArrayString& items, - void **clientData) -{ - Clear(); - - DoInsertItems(items, 0); - - if ( clientData ) - { - unsigned int count = items.GetCount(); - for ( unsigned int n = 0; n < count; n++ ) - { - SetClientData(n, clientData[n]); - } - } -} - // ---------------------------------------------------------------------------- // deleting items // ---------------------------------------------------------------------------- -void wxListBox::Clear() +void wxListBox::DoClear() { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); @@ -785,25 +705,13 @@ void wxListBox::Clear() GTK_LIST(m_list)->last_focus_child = NULL; } - if ( HasClientObjectData() ) - { - // destroy the data (due to Robert's idea of using wxList - // and not wxList we can't just say - // m_clientList.DeleteContents(true) - this would crash! - wxList::compatibility_iterator node = m_clientList.GetFirst(); - while ( node ) - { - delete (wxClientData *)node->GetData(); - node = node->GetNext(); - } - } m_clientList.Clear(); if ( m_strings ) m_strings->Clear(); } -void wxListBox::Delete(unsigned int n) +void wxListBox::DoDeleteOneItem(unsigned int n) { wxCHECK_RET( m_list != NULL, wxT("invalid listbox") ); @@ -811,19 +719,13 @@ void wxListBox::Delete(unsigned int n) wxCHECK_RET( child, wxT("wrong listbox index") ); - GList *list = g_list_append( (GList*) NULL, child->data ); + GList *list = g_list_append( NULL, child->data ); gtk_list_remove_items( m_list, list ); g_list_free( list ); wxList::compatibility_iterator node = m_clientList.Item( n ); if ( node ) { - if ( m_clientDataItemsType == wxClientData_Object ) - { - wxClientData *cd = (wxClientData*)node->GetData(); - delete cd; - } - m_clientList.Erase( node ); } @@ -855,29 +757,6 @@ void* wxListBox::DoGetItemClientData(unsigned int n) const return node->GetData(); } -void wxListBox::DoSetItemClientObject(unsigned int n, wxClientData* clientData) -{ - wxCHECK_RET( m_widget != NULL, wxT("invalid listbox control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_RET( node, wxT("invalid index in wxListBox::DoSetItemClientObject") ); - - // wxItemContainer already deletes data for us - - node->SetData( (wxObject*) clientData ); -} - -wxClientData* wxListBox::DoGetItemClientObject(unsigned int n) const -{ - wxCHECK_MSG( m_widget != NULL, (wxClientData*) NULL, wxT("invalid listbox control") ); - - wxList::compatibility_iterator node = m_clientList.Item( n ); - wxCHECK_MSG( node, (wxClientData *)NULL, - wxT("invalid index in wxListBox::DoGetItemClientObject") ); - - return (wxClientData*) node->GetData(); -} - // ---------------------------------------------------------------------------- // string list access // ---------------------------------------------------------------------------- @@ -892,7 +771,7 @@ wxString wxListBox::GetRealLabel(GList *item) const str = wxString( label->label ); #if wxUSE_CHECKLISTBOX - // checklistboxes have "[±] " prepended to their lables, remove it + // checklistboxes have "[±] " prepended to their lables, remove it // // NB: 4 below is the length of wxCHECKLBOX_STRING from wx/gtk1/checklst.h if ( m_hasCheckBoxes ) @@ -976,7 +855,7 @@ int wxListBox::FindString( const wxString &item, bool bCase ) const int wxListBox::GetSelection() const { - wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") ); + wxCHECK_MSG( m_list != NULL, wxNOT_FOUND, wxT("invalid listbox") ); GList *child = m_list->children; int count = 0; @@ -986,12 +865,12 @@ int wxListBox::GetSelection() const count++; child = child->next; } - return -1; + return wxNOT_FOUND; } int wxListBox::GetSelections( wxArrayInt& aSelections ) const { - wxCHECK_MSG( m_list != NULL, -1, wxT("invalid listbox") ); + wxCHECK_MSG( m_list != NULL, wxNOT_FOUND, wxT("invalid listbox") ); // get the number of selected items first GList *child = m_list->children; @@ -1112,7 +991,7 @@ void wxListBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) GList *child = m_list->children; while (child) { - gtk_tooltips_set_tip( tips, GTK_WIDGET( child->data ), wxConvCurrent->cWX2MB(tip), (gchar*) NULL ); + gtk_tooltips_set_tip( tips, GTK_WIDGET( child->data ), wxConvCurrent->cWX2MB(tip), NULL ); child = child->next; } } @@ -1126,28 +1005,13 @@ GtkWidget *wxListBox::GetConnectWidget() bool wxListBox::IsOwnGtkWindow( GdkWindow *window ) { - return true; - -#if 0 - if (m_widget->window == window) return true; - - if (GTK_WIDGET(m_list)->window == window) return true; - - GList *child = m_list->children; - while (child) - { - GtkWidget *bin = GTK_WIDGET( child->data ); - if (bin->window == window) return true; - child = child->next; - } - - return false; -#endif + return m_widget->window == window || + GTK_WIDGET(m_list)->window == window; } void wxListBox::DoApplyWidgetStyle(GtkRcStyle *style) { - if (m_hasBgCol && m_backgroundColour.Ok()) + if (m_hasBgCol && m_backgroundColour.IsOk()) { GdkWindow *window = GTK_WIDGET(m_list)->window; if ( window ) @@ -1174,9 +1038,9 @@ void wxListBox::DoApplyWidgetStyle(GtkRcStyle *style) void wxListBox::OnInternalIdle() { wxCursor cursor = m_cursor; - if (g_globalCursor.Ok()) cursor = g_globalCursor; + if (g_globalCursor.IsOk()) cursor = g_globalCursor; - if (GTK_WIDGET(m_list)->window && cursor.Ok()) + if (GTK_WIDGET(m_list)->window && cursor.IsOk()) { /* I now set the cursor the anew in every OnInternalIdle call as setting the cursor in a parent window also effects the