X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/04e044c4d6dab8b3164479f9b2d36d5b6a7c8610..2e98aa124386e26c78ca725430c0b0c692db9fc2:/src/gtk/listbox.cpp diff --git a/src/gtk/listbox.cpp b/src/gtk/listbox.cpp index b49029ab73..d908514a19 100644 --- a/src/gtk/listbox.cpp +++ b/src/gtk/listbox.cpp @@ -43,12 +43,6 @@ extern bool g_blockEventsOnScroll; extern wxCursor g_globalCursor; -//----------------------------------------------------------------------------- -// idle system -//----------------------------------------------------------------------------- - -extern void wxapp_install_idle_handler(); -extern bool g_isIdle; //----------------------------------------------------------------------------- // Macro to tell which row the strings are in (1 if native checklist, 0 if not) @@ -144,12 +138,9 @@ gtk_listbox_row_activated_callback(GtkTreeView *treeview, if( (((listbox->GetWindowStyleFlag() & wxLB_MULTIPLE) != 0) || ((listbox->GetWindowStyleFlag() & wxLB_EXTENDED) != 0)) ) - { + { //toggle the selection + send event - if(listbox->IsSelected( sel )) - listbox->GtkSetSelection(sel, FALSE, FALSE); - else - listbox->GtkSetSelection(sel, TRUE, FALSE); + listbox->GtkSetSelection(sel, !listbox->IsSelected( sel ), FALSE); } } } @@ -309,10 +300,10 @@ static gboolean gtk_listitem_select_cb( GtkTreeSelection* selection, listbox->m_blockEvent = FALSE; //Finally, send the wx event - wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); - event.SetEventObject( listbox ); + wxCommandEvent event(wxEVT_COMMAND_LISTBOX_SELECTED, listbox->GetId() ); + event.SetEventObject( listbox ); - // indicate whether this is a selection or a deselection + // indicate whether this is a selection or a deselection event.SetExtraLong( 1 ); event.SetInt(nIndex); @@ -325,7 +316,7 @@ static gboolean gtk_listitem_select_cb( GtkTreeSelection* selection, else if ( listbox->HasClientUntypedData() ) event.SetClientData( gtk_tree_entry_get_userdata(entry) ); - listbox->GetEventHandler()->ProcessEvent( event ); + listbox->GetEventHandler()->ProcessEvent( event ); g_object_unref(G_OBJECT(entry)); return FALSE; //We handled it/did it manually @@ -496,7 +487,6 @@ bool wxListBox::Create( wxWindow *parent, wxWindowID id, WXLISTBOX_DATACOLUMN, NULL); // Now create+set the model (GtkListStore) - first argument # of columns - #if wxUSE_CHECKLISTBOX && wxUSE_NATIVEGTKCHECKLIST if(m_hasCheckBoxes) m_liststore = gtk_list_store_new(2, G_TYPE_BOOLEAN, @@ -615,14 +605,10 @@ void wxListBox::GtkInsertItems(const wxArrayString& items, int nCurCount = wxListBox::GetCount(); wxASSERT_MSG(pos <= nCurCount, wxT("Invalid index passed to wxListBox")); - GtkTreeIter* pIter; - if (pos == nCurCount) - { - pIter = NULL; // append - } - else + GtkTreeIter* pIter = NULL; // append by default + GtkTreeIter iter; + if (pos != nCurCount) { - GtkTreeIter iter; gboolean res = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(m_liststore), &iter, NULL, //NULL = parent = get first @@ -683,12 +669,7 @@ void wxListBox::DoInsertItems(const wxArrayString& items, int pos) int wxListBox::DoAppend( const wxString& item ) { - InvalidateBestSize(); - - //Just call DoInsertItems for now - //RN: Originally I had gtk_list_store_append etc. - // here as an optimization but now the insert - // has been streamlined and its quite a bit of code duplication + // Call DoInsertItems int nWhere = wxListBox::GetCount(); wxArrayString aItems; aItems.Add(item); @@ -711,6 +692,8 @@ void wxListBox::Clear() { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); + InvalidateBestSize(); + gtk_list_store_clear( m_liststore ); /* well, THAT was easy :) */ } @@ -718,6 +701,8 @@ void wxListBox::Delete( int n ) { wxCHECK_RET( m_treeview != NULL, wxT("invalid listbox") ); + InvalidateBestSize(); + GtkTreeIter iter; gboolean res = gtk_tree_model_iter_nth_child( GTK_TREE_MODEL(m_liststore), @@ -987,44 +972,56 @@ void wxListBox::DoSetFirstItem( int n ) if (gdk_pointer_is_grabbed () && GTK_WIDGET_HAS_GRAB (m_treeview)) return; - // terribly efficient (RN:???) - // RN: Note that evidently the vadjustment property "vadjustment" from - // GtkTreeView is different from the "gtk-vadjustment"... - // (i.e. gtk_tree_view_get_vadjustment) - const gchar *vadjustment_key = "gtk-vadjustment"; - guint vadjustment_key_id = g_quark_from_static_string (vadjustment_key); + GtkTreeIter iter; + gtk_tree_model_iter_nth_child( + GTK_TREE_MODEL(m_liststore), + &iter, + NULL, //NULL = parent = get first + n + ); - GtkAdjustment *adjustment = - (GtkAdjustment*) g_object_get_qdata(G_OBJECT (m_treeview), vadjustment_key_id); - wxCHECK_RET( adjustment, wxT("invalid listbox code") ); + GtkTreePath* path = gtk_tree_model_get_path( + GTK_TREE_MODEL(m_liststore), &iter); - // Get the greater of the item heights from each column - gint cellheight = 0, cellheightcur; - GList* columnlist = gtk_tree_view_get_columns(m_treeview); - GList* curlist = columnlist; + // Scroll to the desired cell (0.0 == topleft alignment) + gtk_tree_view_scroll_to_cell(m_treeview, path, NULL, + TRUE, 0.0f, 0.0f); - while(curlist) - { - gtk_tree_view_column_cell_get_size( - GTK_TREE_VIEW_COLUMN(curlist->data), - NULL, NULL, NULL, NULL, - &cellheightcur); + gtk_tree_path_free(path); +} - cellheight = cellheightcur > cellheight ? - cellheightcur : cellheight; +// ---------------------------------------------------------------------------- +// hittest +// ---------------------------------------------------------------------------- - curlist = curlist->next; +int wxListBox::DoListHitTest(const wxPoint& point) const +{ + // need to translate from master window since it is in client coords + gint binx, biny; + gdk_window_get_geometry(gtk_tree_view_get_bin_window(m_treeview), + &binx, &biny, NULL, NULL, NULL); + + GtkTreePath* path; + if ( !gtk_tree_view_get_path_at_pos + ( + m_treeview, + point.x - binx, + point.y - biny, + &path, + NULL, // [out] column (always 0 here) + NULL, // [out] x-coord relative to the cell (not interested) + NULL // [out] y-coord relative to the cell + ) ) + { + return wxNOT_FOUND; } - g_list_free(columnlist); + int index = gtk_tree_path_get_indices(path)[0]; + gtk_tree_path_free(path); - float y = (float) (cellheight * n); - if (y > adjustment->upper - adjustment->page_size) - y = adjustment->upper - adjustment->page_size; - gtk_adjustment_set_value( adjustment, y ); + return index; } - // ---------------------------------------------------------------------------- // helpers // ---------------------------------------------------------------------------- @@ -1039,8 +1036,9 @@ void wxListBox::ApplyToolTip( GtkTooltips *tips, const wxChar *tip ) GtkWidget *wxListBox::GetConnectWidget() { - // return GTK_WIDGET(m_treeview); - return m_widget; + // the correct widget for listbox events (such as mouse clicks for example) + // is m_treeview, not the parent scrolled window + return GTK_WIDGET(m_treeview); } bool wxListBox::IsOwnGtkWindow( GdkWindow *window ) @@ -1088,26 +1086,45 @@ wxSize wxListBox::DoGetBestSize() const { wxCHECK_MSG(m_treeview, wxDefaultSize, wxT("invalid tree view")); - int lbWidth; - int lbHeight; + // Start with a minimum size that's not too small + int cx, cy; + GetTextExtent( wxT("X"), &cx, &cy); + int lbWidth = 3 * cx; + int lbHeight = 10; - // Get the visible area of the tree view - GdkRectangle rect; - gtk_tree_view_get_visible_rect(m_treeview, &rect); - lbWidth = rect.width; - lbHeight = rect.height; + // Get the visible area of the tree view (limit to the 10th item + // so that it isn't too big) + int count = GetCount(); + if (count) + { + int wLine; - // Add room for the scrollbar - lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); + // Find the widest line + for(int i = 0; i < count; i++) { + wxString str(GetString(i)); + GetTextExtent(str, &wLine, NULL); + lbWidth = wxMax(lbWidth, wLine); + } - // And just a bit more - int cx, cy; - GetTextExtent( wxT("X"), &cx, &cy); - lbWidth += 3 * cx; + lbWidth += 3 * cx; + + // And just a bit more for the checkbox if present and then some + // (these are rough guesses) +#if wxUSE_CHECKLISTBOX && wxUSE_NATIVEGTKCHECKLIST + if ( m_hasCheckBoxes ) + { + lbWidth += 35; + cy = cy > 25 ? cy : 25; // rough height of checkbox + } +#endif // 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); + lbHeight = (cy+4) * wxMin(wxMax(count, 3), 10); + } + + // Add room for the scrollbar + lbWidth += wxSystemSettings::GetMetric(wxSYS_VSCROLL_X); wxSize best(lbWidth, lbHeight); CacheBestSize(best);