Applied Ryan's native wxListBox and wxCheckListBox patch

in slightly modified form..


git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37769 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robert Roebling 2006-03-01 21:51:42 +00:00
parent 4eccd3a10f
commit 4a46cbe8c6
8 changed files with 1167 additions and 796 deletions

View File

@ -956,6 +956,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
src/gtk/tbargtk.cpp
src/gtk/textctrl.cpp
src/gtk/tglbtn.cpp
src/gtk/treeentry_gtk.c
src/gtk/utilsres.cpp
</set>
<set var="GTK_HDR" hints="files">
@ -1001,6 +1002,7 @@ IMPORTANT: please read docs/tech/tn0016.txt before modifying this file!
wx/gtk/textctrl.h
wx/gtk/tglbtn.h
wx/gtk/treectrl.h
wx/gtk/treeentry_gtk.h
</set>

View File

@ -24,6 +24,10 @@
#define wxCHECKLBOX_STRING _T("[ ] ")
#endif
//Use the native GTK2.0+ checklist?? You should say YYEEESS unless
//there are like some major bugs or something :)
#define wxUSE_NATIVEGTKCHECKLIST 1
//-----------------------------------------------------------------------------
// wxCheckListBox
// ----------------------------------------------------------------------------
@ -53,6 +57,10 @@ public:
int GetItemHeight() const;
#if wxUSE_NATIVEGTKCHECKLIST
void DoCreateCheckList();
#endif
private:
DECLARE_DYNAMIC_CLASS(wxCheckListBox)
};

View File

@ -10,10 +10,6 @@
#ifndef __GTKLISTBOXH__
#define __GTKLISTBOXH__
#include "wx/list.h"
class WXDLLIMPEXP_BASE wxSortedArrayString;
//-----------------------------------------------------------------------------
// wxListBox
//-----------------------------------------------------------------------------
@ -84,27 +80,29 @@ public:
// implementation from now on
void GtkAddItem( const wxString &item, int pos=-1 );
int GtkGetIndex( GtkWidget *item ) const;
GtkWidget *GetConnectWidget();
bool IsOwnGtkWindow( GdkWindow *window );
GdkWindow* GetGtkBinWindow();
void OnInternalIdle();
#if wxUSE_TOOLTIPS
void ApplyToolTip( GtkTooltips *tips, const wxChar *tip );
#endif // wxUSE_TOOLTIPS
GtkList *m_list;
wxList m_clientList;
struct _GtkTreeView *m_treeview;
struct _GtkListStore *m_liststore;
#if wxUSE_CHECKLISTBOX
bool m_hasCheckBoxes;
#endif // wxUSE_CHECKLISTBOX
int m_prevSelection;
bool m_blockEvent;
bool m_spacePressed;
virtual void FixUpMouseEvent(GtkWidget *widget, wxCoord& x, wxCoord& y);
struct _GtkTreeEntry* GtkGetEntry(int pos) const;
void GtkInsertItems(const wxArrayString& items,
void** clientData, int pos);
void GtkSetSelection(int n, const bool select, const bool blockEvent);
protected:
virtual wxSize DoGetBestSize() const;
@ -119,18 +117,7 @@ protected:
virtual wxClientData* DoGetItemClientObject(int n) const;
void DoApplyWidgetStyle(GtkRcStyle *style);
// return the string label for the given item
wxString GetRealLabel(struct _GList *item) const;
// Widgets that use the style->base colour for the BG colour should
// override this and return true.
virtual bool UseGTKStyleBase() const { return true; }
private:
// this array is only used for controls with wxCB_SORT style, so only
// allocate it if it's needed (hence using pointer)
wxSortedArrayString *m_strings;
DECLARE_DYNAMIC_CLASS(wxListBox)
};

View File

@ -0,0 +1,76 @@
/* ///////////////////////////////////////////////////////////////////////////
// Name: treeentry_gtk.h
// Purpose: GtkTreeEntry - a string/userdata combo for use with treeview
// Author: Ryan Norton
// Id: $Id$
// Copyright: (c) 2006 Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////// */
#ifndef __GTK_TREE_ENTRY_H__
#define __GTK_TREE_ENTRY_H__
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
#include <gtk/gtk.h> /* for gpointer and gchar* etc. */
#include "wx/dlimpexp.h"
#define GTK_TYPE_TREE_ENTRY (gtk_tree_entry_get_type())
#define GTK_TREE_ENTRY(obj) (GTK_CHECK_CAST (obj, gtk_tree_entry_get_type (), GtkTreeEntry))
#define GTK_TREE_ENTRY_CLASS(klass) (GTK_CHECK_CLASS_CAST (klass, gtk_tree_entry_get_type (), GtkTreeEntryClass))
#define GTK_IS_TREE_ENTRY(obj) (GTK_CHECK_TYPE (obj, gtk_tree_entry_get_type ()))
typedef struct _GtkTreeEntry GtkTreeEntry;
typedef struct _GtkTreeEntryClass GtkTreeEntryClass;
typedef void (*GtkTreeEntryDestroy) (GtkTreeEntry* entry, gpointer context);
struct _GtkTreeEntry
{
GObject parent; /* object instance */
gchar* label; /* label - always copied by this object except on get */
gchar* collate_key; /* collate key used for string comparisons/sorting */
gpointer userdata; /* untouched userdata */
GtkTreeEntryDestroy destroy_func; /* called upon destruction - use for freeing userdata etc. */
gpointer destroy_func_data; /* context passed to destroy_func */
};
struct _GtkTreeEntryClass
{
GObjectClass parent;
};
WXDLLIMPEXP_CORE
GtkTreeEntry* gtk_tree_entry_new (void);
WXDLLIMPEXP_CORE
GtkType gtk_tree_entry_get_type (void);
WXDLLIMPEXP_CORE
gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry);
WXDLLIMPEXP_CORE
gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry);
WXDLLIMPEXP_CORE
gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry);
WXDLLIMPEXP_CORE
void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label);
WXDLLIMPEXP_CORE
void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata);
WXDLLIMPEXP_CORE
void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
GtkTreeEntryDestroy destroy_func,
gpointer destroy_func_data);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* __GTK_TREE_ENTRY_H__ */

View File

@ -57,7 +57,19 @@ public:
void OnUncheckFirstItem(wxCommandEvent& event);
void OnToggleFirstItem(wxCommandEvent& event);
void OnToggleSelection(wxCommandEvent& event);
void OnAddItems(wxCommandEvent& event);
void OnToggleSorting(wxCommandEvent& event);
void OnToggleExtended(wxCommandEvent& event);
void OnInsertItemsStart(wxCommandEvent& event);
void OnInsertItemsMiddle(wxCommandEvent& event);
void OnInsertItemsEnd(wxCommandEvent& event);
void OnAppendItems(wxCommandEvent& event);
void OnRemoveItems(wxCommandEvent& event);
void OnGetItemHeight(wxCommandEvent& event);
void OnGetBestSize(wxCommandEvent& event);
void OnMakeItemFirst(wxCommandEvent& event);
void OnListboxSelect(wxCommandEvent& event);
void OnCheckboxToggle(wxCommandEvent& event);
@ -89,7 +101,16 @@ enum
Menu_UncheckFirst,
Menu_ToggleFirst,
Menu_Selection,
Menu_AddItems,
Menu_Extended,
Menu_Sorting,
Menu_InsertItemsStart,
Menu_InsertItemsMiddle,
Menu_InsertItemsEnd,
Menu_AppendItems,
Menu_RemoveItems,
Menu_GetItemHeight,
Menu_GetBestSize,
Menu_MakeItemFirst,
Control_First,
Control_Listbox,
@ -106,7 +127,19 @@ BEGIN_EVENT_TABLE(CheckListBoxFrame, wxFrame)
EVT_MENU(Menu_UncheckFirst, CheckListBoxFrame::OnUncheckFirstItem)
EVT_MENU(Menu_ToggleFirst, CheckListBoxFrame::OnToggleFirstItem)
EVT_MENU(Menu_Selection, CheckListBoxFrame::OnToggleSelection)
EVT_MENU(Menu_AddItems, CheckListBoxFrame::OnAddItems)
EVT_MENU(Menu_Extended, CheckListBoxFrame::OnToggleExtended)
EVT_MENU(Menu_Sorting, CheckListBoxFrame::OnToggleSorting)
EVT_MENU(Menu_InsertItemsStart, CheckListBoxFrame::OnInsertItemsStart)
EVT_MENU(Menu_InsertItemsMiddle, CheckListBoxFrame::OnInsertItemsMiddle)
EVT_MENU(Menu_InsertItemsEnd, CheckListBoxFrame::OnInsertItemsEnd)
EVT_MENU(Menu_AppendItems, CheckListBoxFrame::OnAppendItems)
EVT_MENU(Menu_RemoveItems, CheckListBoxFrame::OnRemoveItems)
EVT_MENU(Menu_GetItemHeight, CheckListBoxFrame::OnGetItemHeight)
EVT_MENU(Menu_GetBestSize, CheckListBoxFrame::OnGetBestSize)
EVT_MENU(Menu_MakeItemFirst, CheckListBoxFrame::OnMakeItemFirst)
EVT_LISTBOX(Control_Listbox, CheckListBoxFrame::OnListboxSelect)
EVT_CHECKLISTBOX(Control_Listbox, CheckListBoxFrame::OnCheckboxToggle)
@ -158,9 +191,21 @@ CheckListBoxFrame::CheckListBoxFrame(wxFrame *frame,
menuList->Append(Menu_UncheckFirst, _T("Uncheck the first item\tCtrl-U"));
menuList->Append(Menu_ToggleFirst, _T("Toggle the first item\tCtrl-T"));
menuList->AppendSeparator();
menuList->Append(Menu_AddItems, _T("Add more items\tCtrl-A"));
menuList->Append(Menu_InsertItemsStart, _T("Insert some item at the beginning"));
menuList->Append(Menu_InsertItemsMiddle, _T("Insert some item at the middle"));
menuList->Append(Menu_InsertItemsEnd, _T("Insert some item at the end"));
menuList->Append(Menu_AppendItems, _T("Append some items\tCtrl-A"));
menuList->Append(Menu_RemoveItems, _T("Remove some items"));
menuList->AppendSeparator();
menuList->AppendCheckItem(Menu_Selection, _T("Multiple selection\tCtrl-M"));
menuList->AppendCheckItem(Menu_Extended, _T("Extended selection"));
menuList->AppendCheckItem(Menu_Sorting, _T("Sorting"));
menuList->AppendSeparator();
menuList->Append(Menu_GetItemHeight, _T("Get the height of an item"));
menuList->Append(Menu_GetBestSize, _T("Get the best size of the checklistbox control"));
menuList->AppendSeparator();
menuList->Append(Menu_MakeItemFirst, _T("Make selected item the first item"));
// put it all together
wxMenuBar *menu_bar = new wxMenuBar;
@ -271,7 +316,7 @@ void CheckListBoxFrame::OnToggleFirstItem(wxCommandEvent& WXUNUSED(event))
m_pListBox->Check(0, !m_pListBox->IsChecked(0));
}
void CheckListBoxFrame::OnAddItems(wxCommandEvent& WXUNUSED(event))
void CheckListBoxFrame::OnInsertItemsStart(wxCommandEvent& WXUNUSED(event))
{
static size_t s_nItem = 0;
wxArrayString items;
@ -282,6 +327,74 @@ void CheckListBoxFrame::OnAddItems(wxCommandEvent& WXUNUSED(event))
m_pListBox->InsertItems(items, 0);//m_pListBox->GetCount());
}
void CheckListBoxFrame::OnInsertItemsMiddle(wxCommandEvent& WXUNUSED(event))
{
static size_t s_nItem = 0;
wxArrayString items;
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
m_pListBox->InsertItems(items, m_pListBox->GetCount() ? 1 : 0);
}
void CheckListBoxFrame::OnInsertItemsEnd(wxCommandEvent& WXUNUSED(event))
{
static size_t s_nItem = 0;
wxArrayString items;
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
items.Add(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
m_pListBox->InsertItems(items, m_pListBox->GetCount() );
}
void CheckListBoxFrame::OnAppendItems(wxCommandEvent& WXUNUSED(event))
{
static size_t s_nItem = 0;
m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
m_pListBox->Append(wxString::Format(_T("New item %lu"), (unsigned long)++s_nItem));
}
void CheckListBoxFrame::OnRemoveItems(wxCommandEvent& WXUNUSED(event))
{
if(m_pListBox->GetCount())
m_pListBox->Delete(0);
if(m_pListBox->GetCount())
m_pListBox->Delete(0);
if(m_pListBox->GetCount())
m_pListBox->Delete(0);
}
void CheckListBoxFrame::OnGetItemHeight(wxCommandEvent& WXUNUSED(event))
{
int height = m_pListBox->GetItemHeight();
wxMessageBox(wxString::Format(wxT("Height of an item is:%i"),
height
)
);
}
void CheckListBoxFrame::OnGetBestSize(wxCommandEvent& WXUNUSED(event))
{
wxSize bestSize = m_pListBox->GetBestSize();
wxMessageBox(wxString::Format(wxT("Best size of the checklistbox is:[%i,%i]"),
bestSize.x, bestSize.y
)
);
}
void CheckListBoxFrame::OnMakeItemFirst(wxCommandEvent& WXUNUSED(event))
{
if(m_pListBox->GetSelection() != -1)
m_pListBox->SetFirstItem(m_pListBox->GetSelection());
else
wxMessageBox(wxT("Nothing selected!"));
}
void CheckListBoxFrame::OnToggleSelection(wxCommandEvent& event)
{
wxSizer *sizer = m_panel->GetSizer();
@ -296,6 +409,34 @@ void CheckListBoxFrame::OnToggleSelection(wxCommandEvent& event)
m_panel->Layout();
}
void CheckListBoxFrame::OnToggleExtended(wxCommandEvent& event)
{
wxSizer *sizer = m_panel->GetSizer();
sizer->Detach( m_pListBox );
delete m_pListBox;
CreateCheckListbox(event.IsChecked() ? wxLB_EXTENDED : 0);
sizer->Insert(0, m_pListBox, 1, wxGROW | wxALL, 10);
m_panel->Layout();
}
void CheckListBoxFrame::OnToggleSorting(wxCommandEvent& event)
{
wxSizer *sizer = m_panel->GetSizer();
sizer->Detach( m_pListBox );
delete m_pListBox;
CreateCheckListbox(event.IsChecked() ? wxLB_SORT : 0);
sizer->Insert(0, m_pListBox, 1, wxGROW | wxALL, 10);
m_panel->Layout();
}
void CheckListBoxFrame::OnListboxSelect(wxCommandEvent& event)
{
int nSel = event.GetSelection();

View File

@ -2,6 +2,7 @@
// Name: checklst.cpp
// Purpose:
// Author: Robert Roebling
// Modified by: Ryan Norton (Native GTK2.0+ checklist)
// Id: $Id$
// Copyright: (c) 1998 Robert Roebling
// Licence: wxWindows licence
@ -15,17 +16,35 @@
#if wxUSE_CHECKLISTBOX
#include "wx/checklst.h"
// FIXME: We use GtkList to implement wxListBox
#ifdef GTK_DISABLE_DEPRECATED
#undef GTK_DISABLE_DEPRECATED
#endif
#include "wx/gtk/private.h"
#include "wx/gtk/treeentry_gtk.h"
#include <gdk/gdk.h>
#include <gtk/gtk.h>
//-----------------------------------------------------------------------------
// "toggled"
//-----------------------------------------------------------------------------
#if wxUSE_NATIVEGTKCHECKLIST
extern "C" {
static void gtk_checklist_toggled(GtkCellRendererToggle *renderer,
gchar *stringpath,
wxCheckListBox *listbox)
{
wxCHECK_RET( listbox->m_treeview != NULL, wxT("invalid listbox") );
GtkTreePath* path = gtk_tree_path_new_from_string(stringpath);
wxCommandEvent new_event( wxEVT_COMMAND_CHECKLISTBOX_TOGGLED,
listbox->GetId() );
new_event.SetEventObject( listbox );
new_event.SetInt( gtk_tree_path_get_indices(path)[0] );
gtk_tree_path_free(path);
listbox->Check( new_event.GetInt(), !listbox->IsChecked(new_event.GetInt()));
listbox->GetEventHandler()->ProcessEvent( new_event );
}
}
#endif
//-----------------------------------------------------------------------------
// wxCheckListBox
//-----------------------------------------------------------------------------
@ -63,17 +82,90 @@ wxCheckListBox::wxCheckListBox(wxWindow *parent, wxWindowID id,
style, validator, name );
}
#if wxUSE_NATIVEGTKCHECKLIST
void wxCheckListBox::DoCreateCheckList()
{
//Create the checklist in our treeview and set up events for it
GtkCellRenderer* renderer =
gtk_cell_renderer_toggle_new();
GtkTreeViewColumn* column =
gtk_tree_view_column_new_with_attributes( "", renderer,
"active", 0,
NULL );
gtk_tree_view_column_set_fixed_width(column, 20);
gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
gtk_tree_view_column_set_clickable(column, TRUE);
g_signal_connect (renderer, "toggled",
G_CALLBACK (gtk_checklist_toggled),
this);
gtk_tree_view_append_column(m_treeview, column);
}
bool wxCheckListBox::IsChecked( int index ) const
{
wxCHECK_MSG( m_list != NULL, FALSE, wxT("invalid checklistbox") );
wxCHECK_MSG( m_treeview != NULL, FALSE, wxT("invalid checklistbox") );
GList *child = g_list_nth( m_list->children, index );
if (child)
GtkTreeIter iter;
gboolean res = gtk_tree_model_iter_nth_child(
GTK_TREE_MODEL(m_liststore),
&iter, NULL, //NULL = parent = get first
index
);
if(!res)
return false;
GValue value = {0, };
gtk_tree_model_get_value(GTK_TREE_MODEL(m_liststore),
&iter,
0, //column
&value);
return g_value_get_boolean(&value) == TRUE ? true : false;
}
void wxCheckListBox::Check( int index, bool check )
{
wxCHECK_RET( m_treeview != NULL, wxT("invalid checklistbox") );
GtkTreeIter iter;
gboolean res = gtk_tree_model_iter_nth_child(
GTK_TREE_MODEL(m_liststore),
&iter, NULL, //NULL = parent = get first
index
);
if(!res)
return;
gtk_list_store_set(m_liststore,
&iter,
0, //column
check ? TRUE : FALSE, -1);
}
int wxCheckListBox::GetItemHeight() const
{
wxCHECK_MSG( m_treeview != NULL, 0, wxT("invalid listbox"));
gint height;
gtk_tree_view_column_cell_get_size(
gtk_tree_view_get_column(m_treeview, 0),
NULL, NULL, NULL, NULL,
&height);
return height;
}
#else //NON-NATIVE
bool wxCheckListBox::IsChecked( int index ) const
{
wxCHECK_MSG( m_treeview != NULL, FALSE, wxT("invalid checklistbox") );
GtkTreeEntry* entry = GtkGetEntry(index);
if (entry)
{
GtkBin *bin = GTK_BIN( child->data );
GtkLabel *label = GTK_LABEL( bin->child );
wxString str( wxGTK_CONV_BACK( label->label ) );
wxString str( wxGTK_CONV_BACK( gtk_tree_entry_get_label(entry) ) );
return str.GetChar(1) == wxCHECKLBOX_CHECKED;
}
@ -84,22 +176,19 @@ bool wxCheckListBox::IsChecked( int index ) const
void wxCheckListBox::Check( int index, bool check )
{
wxCHECK_RET( m_list != NULL, wxT("invalid checklistbox") );
wxCHECK_RET( m_treeview != NULL, wxT("invalid checklistbox") );
GList *child = g_list_nth( m_list->children, index );
if (child)
GtkTreeEntry* entry = GtkGetEntry(index);
if (entry)
{
GtkBin *bin = GTK_BIN( child->data );
GtkLabel *label = GTK_LABEL( bin->child );
wxString str( wxGTK_CONV_BACK( label->label ) );
wxString str( wxGTK_CONV_BACK( gtk_tree_entry_get_label(entry) ) );
if (check == (str.GetChar(1) == wxCHECKLBOX_CHECKED))
return;
str.SetChar( 1, check ? wxCHECKLBOX_CHECKED : wxCHECKLBOX_UNCHECKED );
gtk_label_set_text( label, wxGTK_CONV( str ) );
gtk_tree_entry_set_label( entry, wxGTK_CONV( str ) );
return;
}
@ -113,4 +202,6 @@ int wxCheckListBox::GetItemHeight() const
return 22;
}
#endif
#endif //wxUSE_NATIVEGTKCHECKLIST
#endif //wxUSE_CHECKLISTBOX

File diff suppressed because it is too large Load Diff

175
src/gtk/treeentry_gtk.c Normal file
View File

@ -0,0 +1,175 @@
/* ///////////////////////////////////////////////////////////////////////////
// Name: src/gtk/treeentry_gtk.c
// Purpose: GtkTreeEntry implementation
// Author: Ryan Norton
// Id: $Id$
// Copyright: (c) 2006 Ryan Norton
// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////// */
#include "wx/gtk/treeentry_gtk.h"
/*
GtkTreeEntry
The main reason for this class is to have a holder for both a string
and userdata for us to use in wxListXXX classes.
This is transformable to a string for the Gtk implementations,
and the string passed in is duplicated and freed upon destruction.
As mentioned the real magic here is the transforming it to a string
which lets us use it as a entry in a GtkTreeView/GtkListStore
and still display it. Otherwise we would need to implement our
own model etc..
*/
/* forwards */
static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass);
static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class);
static void gtk_tree_entry_string_transform_func(const GValue *src_value,
GValue *dest_value);
static void gtk_tree_entry_dispose(GObject* obj);
/* public */
GtkTreeEntry*
gtk_tree_entry_new()
{
return GTK_TREE_ENTRY(g_object_new(GTK_TYPE_TREE_ENTRY, NULL));
}
GtkType
gtk_tree_entry_get_type ()
{
static GtkType tree_entry_type = 0;
if (!tree_entry_type)
{
static const GTypeInfo tree_entry_info =
{
sizeof (GtkTreeEntryClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) gtk_tree_entry_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GtkTreeEntry),
16, /* n_preallocs */
(GInstanceInitFunc) gtk_tree_entry_init, /*instance_init*/
};
tree_entry_type = g_type_register_static (G_TYPE_OBJECT, "GtkTreeEntry",
&tree_entry_info,
(GTypeFlags)0);
g_value_register_transform_func(tree_entry_type, G_TYPE_STRING,
gtk_tree_entry_string_transform_func);
}
return tree_entry_type;
}
gchar* gtk_tree_entry_get_collate_key (GtkTreeEntry* entry)
{
return entry->collate_key;
}
gchar* gtk_tree_entry_get_label (GtkTreeEntry* entry)
{
g_assert(GTK_IS_TREE_ENTRY(entry));
return entry->label;
}
gpointer gtk_tree_entry_get_userdata (GtkTreeEntry* entry)
{
g_assert(GTK_IS_TREE_ENTRY(entry));
return entry->userdata;
}
void gtk_tree_entry_set_label (GtkTreeEntry* entry, const gchar* label)
{
g_assert(GTK_IS_TREE_ENTRY(entry));
/* free previous if it exists */
if(entry->label)
{
g_free(entry->label);
g_free(entry->collate_key);
}
entry->label = g_strdup(label);
entry->collate_key = g_utf8_collate_key(label, -1); /* -1 == null terminated */
}
void gtk_tree_entry_set_userdata (GtkTreeEntry* entry, gpointer userdata)
{
g_assert(GTK_IS_TREE_ENTRY(entry));
entry->userdata = userdata;
}
void gtk_tree_entry_set_destroy_func (GtkTreeEntry* entry,
GtkTreeEntryDestroy destroy_func,
gpointer destroy_func_data)
{
g_assert(GTK_IS_TREE_ENTRY(entry));
entry->destroy_func = destroy_func;
entry->destroy_func_data = destroy_func_data;
}
/* private */
static void gtk_tree_entry_class_init(GtkTreeEntryClass* klass)
{
GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
gobject_class->dispose = gtk_tree_entry_dispose;
}
static void gtk_tree_entry_init (GTypeInstance* instance, gpointer g_class)
{
GtkTreeEntry* entry = (GtkTreeEntry*) instance;
/* clear */
entry->label = NULL;
entry->collate_key = NULL;
entry->userdata = NULL;
entry->destroy_func_data = NULL;
entry->destroy_func = NULL;
}
static void gtk_tree_entry_string_transform_func(const GValue *src_value,
GValue *dest_value)
{
/* Make sure src is a treeentry and dest can hold a string */
g_assert(GTK_IS_TREE_ENTRY(src_value->data[0].v_pointer));
g_assert(G_VALUE_HOLDS(dest_value, G_TYPE_STRING));
/* TODO: Use strdup here or just pass it? */
GtkTreeEntry* entry = GTK_TREE_ENTRY(src_value->data[0].v_pointer);
g_value_set_string(dest_value, g_strdup(entry->label));
}
static void gtk_tree_entry_dispose(GObject* obj)
{
g_assert(GTK_IS_TREE_ENTRY(obj));
GtkTreeEntry* entry = GTK_TREE_ENTRY(obj);
/* free label if it exists */
if(entry->label)
{
g_free(entry->label);
g_free(entry->collate_key);
entry->label = NULL;
entry->collate_key = NULL;
}
/* call destroy callback if it exists */
if(entry->destroy_func)
{
(*entry->destroy_func) (entry, entry->destroy_func_data);
entry->destroy_func = NULL;
entry->destroy_func_data = NULL;
}
/* clear userdata */
entry->userdata = NULL;
}