X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/584ad2a32fec156c6049145d7ece9a33213aea28..37780c641b5f464f81cab4419fd4e5128871bd9e:/src/gtk/listbox.cpp diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index a4304cfe01..d8810ddae0 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -51,6 +51,8 @@ extern bool g_blockEventsOnDrag; extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; extern wxWindowGTK *g_delayedFocus; +extern wxWindowGTK *g_focusWindow; +extern wxWindowGTK *g_focusWindowLast; static bool g_hasDoubleClicked = FALSE; @@ -87,6 +89,68 @@ extern "C" gint wxlistbox_idle_callback( gpointer gdata ) return TRUE; } +//----------------------------------------------------------------------------- +// "focus_in_event" +//----------------------------------------------------------------------------- + +static gint gtk_listitem_focus_in_callback( GtkWidget *widget, + GdkEvent *WXUNUSED(event), + wxWindow *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + g_focusWindowLast = + g_focusWindow = win; + + // does the window itself think that it has the focus? + if ( !win->m_hasFocus ) + { + // not yet, notify it + win->m_hasFocus = TRUE; + + wxChildFocusEvent eventChildFocus(win); + (void)win->GetEventHandler()->ProcessEvent(eventChildFocus); + + wxFocusEvent eventFocus(wxEVT_SET_FOCUS, win->GetId()); + eventFocus.SetEventObject(win); + + (void)win->GetEventHandler()->ProcessEvent(eventFocus); + } + + return FALSE; +} + +//----------------------------------------------------------------------------- +// "focus_out_event" +//----------------------------------------------------------------------------- + +static gint gtk_listitem_focus_out_callback( GtkWidget *widget, GdkEventFocus *gdk_event, wxWindowGTK *win ) +{ + if (g_isIdle) + wxapp_install_idle_handler(); + + g_focusWindow = (wxWindowGTK *)NULL; + + // don't send the window a kill focus event if it thinks that it doesn't + // have focus already + if ( win->m_hasFocus ) + { + win->m_hasFocus = FALSE; + + wxFocusEvent event( wxEVT_KILL_FOCUS, win->GetId() ); + event.SetEventObject( win ); + + // even if we did process the event in wx code, still let GTK itself + // 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 ); + } + + return FALSE; +} + //----------------------------------------------------------------------------- // "button_release_event" //----------------------------------------------------------------------------- @@ -223,6 +287,44 @@ gtk_listbox_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_event, wxLis } #endif // wxUSE_CHECKLISTBOX + // Check or uncheck item with SPACE + if ((gdk_event->keyval == ' ') && (!ret) && + (((listbox->GetWindowStyleFlag() & wxLB_MULTIPLE) != 0) || + ((listbox->GetWindowStyleFlag() & wxLB_EXTENDED) != 0)) ) + { + int sel = listbox->GtkGetIndex( widget ); + + if (sel != -1) + { + ret = TRUE; + + if (listbox->IsSelected( sel )) + gtk_list_unselect_item( listbox->m_list, sel ); + else + gtk_list_select_item( listbox->m_list, sel ); + + wxCommandEvent new_event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); + new_event.SetEventObject( listbox ); + wxArrayInt aSelections; + int n, count = listbox->GetSelections(aSelections); + if ( count > 0 ) + { + n = aSelections[0]; + if ( listbox->HasClientObjectData() ) + new_event.SetClientObject( listbox->GetClientObject(n) ); + else if ( listbox->HasClientUntypedData() ) + new_event.SetClientData( listbox->GetClientData(n) ); + new_event.SetString( listbox->GetString(n) ); + } + else + { + n = -1; + } + new_event.m_commandInt = n; + listbox->GetEventHandler()->ProcessEvent( new_event ); + } + } + if (ret) { gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); @@ -404,16 +506,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(); - InheritAttributes(); - - Show( TRUE ); + PostCreation(size); + SetBestSize(size); // need this too because this is a wxControlWithItems return TRUE; } @@ -445,6 +541,8 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos) wxASSERT_MSG( m_clientList.GetCount() == (size_t)GetCount(), wxT("bug in client data management") ); + InvalidateBestSize(); + GList *children = m_list->children; int length = g_list_length(children); @@ -501,6 +599,8 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos) int wxListBox::DoAppend( const wxString& item ) { + InvalidateBestSize(); + if (m_strings) { // need to determine the index @@ -571,6 +671,14 @@ void wxListBox::GtkAddItem( const wxString &item, int pos ) (GtkSignalFunc)gtk_listbox_key_press_callback, (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(list_item), "focus_in_event", + GTK_SIGNAL_FUNC(gtk_listitem_focus_in_callback), (gpointer)this ); + + gtk_signal_connect( GTK_OBJECT(list_item), "focus_out_event", + GTK_SIGNAL_FUNC(gtk_listitem_focus_out_callback), (gpointer)this ); + + ConnectWidget( list_item ); gtk_widget_show( list_item ); @@ -580,19 +688,21 @@ void wxListBox::GtkAddItem( const wxString &item, int pos ) gtk_widget_realize( list_item ); gtk_widget_realize( GTK_BIN(list_item)->child ); - // Apply current widget style to the new list_item - if (m_widgetStyle) - { - gtk_widget_set_style( GTK_WIDGET( list_item ), m_widgetStyle ); - GtkBin *bin = GTK_BIN( list_item ); - GtkWidget *label = GTK_WIDGET( bin->child ); - gtk_widget_set_style( label, m_widgetStyle ); - } - #if wxUSE_TOOLTIPS if (m_tooltip) m_tooltip->Apply( this ); #endif } + + // Apply current widget style to the new list_item + GtkRcStyle *style = CreateWidgetStyle(); + if (style) + { + gtk_widget_modify_style( GTK_WIDGET( list_item ), style ); + GtkBin *bin = GTK_BIN( list_item ); + GtkWidget *label = GTK_WIDGET( bin->child ); + gtk_widget_modify_style( label, style ); + gtk_rc_style_unref( style ); + } } void wxListBox::DoSetItems( const wxArrayString& items, @@ -967,11 +1077,15 @@ void wxListBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) GtkWidget *wxListBox::GetConnectWidget() { - return GTK_WIDGET(m_list); + // return GTK_WIDGET(m_list); + return m_widget; } 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; @@ -985,13 +1099,12 @@ bool wxListBox::IsOwnGtkWindow( GdkWindow *window ) } return FALSE; +#endif } -void wxListBox::ApplyWidgetStyle() +void wxListBox::DoApplyWidgetStyle(GtkRcStyle *style) { - SetWidgetStyle(); - - if (m_backgroundColour.Ok()) + if (m_hasBgCol && m_backgroundColour.Ok()) { GdkWindow *window = GTK_WIDGET(m_list)->window; if ( window ) @@ -1005,11 +1118,11 @@ void wxListBox::ApplyWidgetStyle() GList *child = m_list->children; while (child) { - gtk_widget_set_style( GTK_WIDGET(child->data), m_widgetStyle ); + gtk_widget_modify_style( GTK_WIDGET(child->data), style ); GtkBin *bin = GTK_BIN( child->data ); GtkWidget *label = GTK_WIDGET( bin->child ); - gtk_widget_set_style( label, m_widgetStyle ); + gtk_widget_modify_style( label, style ); child = child->next; } @@ -1082,7 +1195,9 @@ wxSize wxListBox::DoGetBestSize() const // make it too small neither lbHeight = (cy+4) * wxMin(wxMax(GetCount(), 3), 10); - return wxSize(lbWidth, lbHeight); + wxSize best(lbWidth, lbHeight); + CacheBestSize(best); + return best; } void wxListBox::FixUpMouseEvent(GtkWidget *widget, wxCoord& x, wxCoord& y) @@ -1093,5 +1208,13 @@ void wxListBox::FixUpMouseEvent(GtkWidget *widget, wxCoord& x, wxCoord& y) y += widget->allocation.y; } + +// static +wxVisualAttributes +wxListBox::GetClassDefaultAttributes(wxWindowVariant WXUNUSED(variant)) +{ + return GetDefaultAttributesFromGTKWidget(gtk_list_new, true); +} + #endif // wxUSE_LISTBOX