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:
parent
4eccd3a10f
commit
4a46cbe8c6
@ -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>
|
||||
|
||||
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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)
|
||||
};
|
||||
|
||||
|
76
include/wx/gtk/treeentry_gtk.h
Normal file
76
include/wx/gtk/treeentry_gtk.h
Normal 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__ */
|
@ -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();
|
||||
|
@ -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
|
||||
|
1387
src/gtk/listbox.cpp
1387
src/gtk/listbox.cpp
File diff suppressed because it is too large
Load Diff
175
src/gtk/treeentry_gtk.c
Normal file
175
src/gtk/treeentry_gtk.c
Normal 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;
|
||||
}
|
Loading…
Reference in New Issue
Block a user