diff --git a/combobox.go b/combobox.go index cadce35..fbeb365 100644 --- a/combobox.go +++ b/combobox.go @@ -102,6 +102,19 @@ func (c *Combobox) SelectedIndex() int { return -1 } +// Len returns the number of items in the Combobox. +// +// On platforms for which this function may return an error, it panics if one is returned. +func (c *Combobox) Len() int { + c.lock.Lock() + defer c.lock.Unlock() + + if c.created { + return c.sysData.len() + } + return len(c.initItems) +} + func (c *Combobox) make(window *sysData) (err error) { c.lock.Lock() defer c.lock.Unlock() diff --git a/gtkcalls_unix.go b/gtkcalls_unix.go index 6d9706d..bde6b74 100644 --- a/gtkcalls_unix.go +++ b/gtkcalls_unix.go @@ -155,6 +155,13 @@ func gtk_combo_box_text_remove(widget *gtkWidget, index int) { C.gtk_combo_box_text_remove(togtkcombobox(widget), C.gint(index)) } +func gtkComboBoxLen(widget *gtkWidget) int { + cb := (*C.GtkComboBox)(unsafe.Pointer(widget)) + model := C.gtk_combo_box_get_model(cb) + // this is the same as with a Listbox so + return gtkTreeModelListLen(model) +} + func gtk_entry_new() *gtkWidget { return fromgtkwidget(C.gtk_entry_new()) } diff --git a/listbox.go b/listbox.go index e95b5cf..66ff398 100644 --- a/listbox.go +++ b/listbox.go @@ -96,6 +96,19 @@ func (l *Listbox) SelectedIndices() []int { return nil } +// Len returns the number of items in the Listbox. +// +// On platforms for which this function may return an error, it panics if one is returned. +func (l *Listbox) Len() int { + l.lock.Lock() + defer l.lock.Unlock() + + if l.created { + return l.sysData.len() + } + return len(l.initItems) +} + func (l *Listbox) make(window *sysData) (err error) { l.lock.Lock() defer l.lock.Unlock() diff --git a/listbox_unix.go b/listbox_unix.go index 10f2680..cc6ca44 100644 --- a/listbox_unix.go +++ b/listbox_unix.go @@ -211,3 +211,15 @@ func gListboxDelete(widget *gtkWidget, index int) { } C.gtk_list_store_remove(ls, &iter) } + +// this is a separate function because Combobox uses it too +func gtkTreeModelListLen(model *C.GtkTreeModel) int { + // "As a special case, if iter is NULL, then the number of toplevel nodes is returned." + return int(C.gtk_tree_model_iter_n_children(model, (*C.GtkTreeIter)(nil))) +} + +func gListboxLen(widget *gtkWidget) int { + tv := getTreeViewFrom(widget) + model := C.gtk_tree_view_get_model(tv) + return gtkTreeModelListLen(model) +} diff --git a/sysdata.go b/sysdata.go index 4574684..eb62107 100644 --- a/sysdata.go +++ b/sysdata.go @@ -67,6 +67,9 @@ func (c *cSysData) preferredSize() (int, int) { func (c *cSysData) setProgress(int) { panic(runtime.GOOS + " sysData does not define setProgress()") } +func (c *cSysData) len() int { + panic(runtime.GOOS + " sysData does not define len()") +} // signal sends the event signal. This raise is done asynchronously to avoid deadlocking the UI task. // Thanks skelterjohn for this techinque: if we can't queue any more events, drop them diff --git a/sysdata_unix.go b/sysdata_unix.go index fbfbf80..8b49cad 100644 --- a/sysdata_unix.go +++ b/sysdata_unix.go @@ -25,6 +25,7 @@ type classData struct { selMulti func(widget *gtkWidget) []int smtexts func(widget *gtkWidget) []string delete func(widget *gtkWidget, index int) + len func(widget *gtkWidget) int // ... signals map[string]func(*sysData) func() bool } @@ -84,6 +85,7 @@ var classTypes = [nctypes]*classData{ insert: gtk_combo_box_text_insert_text, selected: gtk_combo_box_get_active, delete: gtk_combo_box_text_remove, + len: gtkComboBoxLen, }, c_lineedit: &classData{ make: gtk_entry_new, @@ -107,6 +109,7 @@ var classTypes = [nctypes]*classData{ selMulti: gListboxSelectedMulti, smtexts: gListboxSelMultiTexts, delete: gListboxDelete, + len: gListboxLen, }, c_progressbar: &classData{ make: gtk_progress_bar_new, @@ -294,3 +297,12 @@ func (s *sysData) setProgress(percent int) { } <-ret } + +func (s *sysData) len() int { + ret := make(chan int) + defer close(ret) + uitask <- func() { + ret <- classTypes[s.ctype].len(s.widget) + } + return <-ret +} diff --git a/test/main.go b/test/main.go index 31fa243..fb21024 100644 --- a/test/main.go +++ b/test/main.go @@ -117,11 +117,11 @@ mainloop: lb2.Delete(4) case <-b3.Clicked: MsgBox("List Info", - "cb1: %d %q\ncb2: %d %q\nlb1: %d %q\nlb2: %d %q", - cb1.SelectedIndex(), cb1.Selection(), - cb2.SelectedIndex(), cb2.Selection(), - lb1.SelectedIndices(), lb1.Selection(), - lb2.SelectedIndices(), lb2.Selection()) + "cb1: %d %q (len %d)\ncb2: %d %q (len %d)\nlb1: %d %q (len %d)\nlb2: %d %q (len %d)", + cb1.SelectedIndex(), cb1.Selection(), cb1.Len(), + cb2.SelectedIndex(), cb2.Selection(), cb2.Len(), + lb1.SelectedIndices(), lb1.Selection(), lb1.Len(), + lb2.SelectedIndices(), lb2.Selection(), lb2.Len()) case <-incButton.Clicked: prog++ if prog > 100 {