summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPietro Gagliardi <[email protected]>2014-02-16 23:50:54 -0500
committerPietro Gagliardi <[email protected]>2014-02-16 23:50:54 -0500
commit0856e953be71f13e4062c4e2ca44002ca4a68ac3 (patch)
treee577566011b874842fef687a92e47c6f7ded6053
parent919e89ca7e4e421cac11ac292470a1f7bf4e66d8 (diff)
Added GTK+ listboxes... sort of. This whole thing is so broken it's funny.
-rw-r--r--gtkcalls_unix.go134
-rw-r--r--sysdata_unix.go39
2 files changed, 161 insertions, 12 deletions
diff --git a/gtkcalls_unix.go b/gtkcalls_unix.go
index c283034..f7c319e 100644
--- a/gtkcalls_unix.go
+++ b/gtkcalls_unix.go
@@ -13,6 +13,10 @@ import (
// #include <gtk/gtk.h>
// /* because cgo is flaky with macros */
// void gSignalConnect(GtkWidget *widget, char *signal, GCallback callback, void *data) { g_signal_connect(widget, signal, callback, data); }
+// /* because cgo seems to choke on ... */
+// void gtkTreeModelGet(GtkTreeModel *model, GtkTreeIter *iter, gchar **gs) { gtk_tree_model_get(model, iter, 0, gs, -1); }
+// GtkListStore *gtkListStoreNew(void) { return gtk_list_store_new(1, G_TYPE_STRING); }
+// void gtkListStoreSet(GtkListStore *ls, GtkTreeIter *iter, char *gs) { gtk_list_store_set(ls, iter, 0, (gchar *) gs, -1); }
import "C"
// BIG TODO reduce the amount of explicit casting
@@ -200,3 +204,133 @@ func gtk_label_set_text(widget *gtkWidget, text string) {
func gtk_label_get_text(widget *gtkWidget) string {
return C.GoString((*C.char)(unsafe.Pointer(C.gtk_label_get_text((*C.GtkLabel)(unsafe.Pointer(widget))))))
}
+
+func gListboxNew(multisel bool) *gtkWidget {
+ store := C.gtkListStoreNew()
+ widget := C.gtk_tree_view_new_with_model((*C.GtkTreeModel)(unsafe.Pointer(store)))
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ sel := C.GTK_SELECTION_SINGLE
+ if multisel {
+ sel = C.GTK_SELECTION_MULTIPLE
+ }
+ C.gtk_tree_selection_set_mode(C.gtk_tree_view_get_selection(tv), C.GtkSelectionMode(sel))
+ return (*gtkWidget)(unsafe.Pointer(widget))
+}
+
+func gListboxNewSingle() *gtkWidget {
+ return gListboxNew(false)
+}
+
+func gListboxNewMulti() *gtkWidget {
+ return gListboxNew(true)
+}
+
+func gListboxText(widget *gtkWidget) string {
+ var model *C.GtkTreeModel
+ var iter C.GtkTreeIter
+ var gs *C.gchar
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ sel := C.gtk_tree_view_get_selection(tv)
+ if !fromgbool(C.gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ return ""
+ }
+ C.gtkTreeModelGet(model, &iter, &gs)
+ return C.GoString((*C.char)(unsafe.Pointer(gs)))
+}
+
+func gListboxAppend(widget *gtkWidget, what string) {
+ var iter C.GtkTreeIter
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
+ C.gtk_list_store_append(ls, &iter)
+ cwhat := C.CString(what)
+ defer C.free(unsafe.Pointer(cwhat))
+ C.gtkListStoreSet(ls, &iter, cwhat)
+}
+
+func gListboxInsert(widget *gtkWidget, index int, what string) {
+ var iter C.GtkTreeIter
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
+ C.gtk_list_store_insert(ls, &iter, C.gint(index))
+ cwhat := C.CString(what)
+ defer C.free(unsafe.Pointer(cwhat))
+ C.gtkListStoreSet(ls, &iter, cwhat)
+}
+
+func gListboxSelected(widget *gtkWidget) int {
+ var model *C.GtkTreeModel
+ var iter C.GtkTreeIter
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ sel := C.gtk_tree_view_get_selection(tv)
+ if !fromgbool(C.gtk_tree_selection_get_selected(sel, &model, &iter)) {
+ return -1
+ }
+ path := C.gtk_tree_model_get_path(model, &iter)
+ return int(*C.gtk_tree_path_get_indices(path))
+}
+
+func gListboxSelectedMulti(widget *gtkWidget) (indices []int) {
+ var model *C.GtkTreeModel
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ sel := C.gtk_tree_view_get_selection(tv)
+ rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
+ defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
+ len := C.g_list_length(rows)
+ if len == 0 {
+ return nil
+ }
+ indices = make([]int, len)
+ for i := C.guint(0); i < len; i++ {
+ d := (*C.GtkTreeRowReference)(unsafe.Pointer(rows.data))
+ path := C.gtk_tree_row_reference_get_path(d)
+ indices[i] = int(*C.gtk_tree_path_get_indices(path))
+ rows = rows.next
+ }
+ return indices
+}
+
+func gListboxSelMultiTexts(widget *gtkWidget) (texts []string) {
+ var model *C.GtkTreeModel
+ var iter C.GtkTreeIter
+ var gs *C.gchar
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ sel := C.gtk_tree_view_get_selection(tv)
+ rows := C.gtk_tree_selection_get_selected_rows(sel, &model)
+ defer C.g_list_free_full(rows, C.GDestroyNotify(unsafe.Pointer(C.gtk_tree_path_free)))
+ len := C.g_list_length(rows)
+ if len == 0 {
+ return nil
+ }
+ texts = make([]string, len)
+ for i := C.guint(0); i < len; i++ {
+ d := (*C.GtkTreeRowReference)(unsafe.Pointer(rows.data))
+ path := C.gtk_tree_row_reference_get_path(d)
+ if !fromgbool(C.gtk_tree_model_get_iter(model, &iter, path)) {
+ // TODO
+ return
+ }
+ C.gtkTreeModelGet(model, &iter, &gs)
+ texts[i] = C.GoString((*C.char)(unsafe.Pointer(gs)))
+ rows = rows.next
+ }
+ return texts
+}
+
+func gListboxDelete(widget *gtkWidget, index int) {
+ var iter C.GtkTreeIter
+
+ tv := (*C.GtkTreeView)(unsafe.Pointer(widget))
+ ls := (*C.GtkListStore)(unsafe.Pointer(C.gtk_tree_view_get_model(tv)))
+ if !fromgbool(C.gtk_tree_model_iter_nth_child((*C.GtkTreeModel)(unsafe.Pointer(ls)), &iter, (*C.GtkTreeIter)(nil), C.gint(index))) { // no such index
+ // TODO
+ return
+ }
+ C.gtk_list_store_remove(ls, &iter)
+}
diff --git a/sysdata_unix.go b/sysdata_unix.go
index fd15e1b..d2e6d16 100644
--- a/sysdata_unix.go
+++ b/sysdata_unix.go
@@ -23,7 +23,8 @@ type classData struct {
append func(widget *gtkWidget, text string)
insert func(widget *gtkWidget, index int, text string)
selected func(widget *gtkWidget) int
- // ...
+ selMulti func(widget *gtkWidget) []int
+ smtexts func(widget *gtkWidget) []string
delete func(widget *gtkWidget, index int)
// ...
signals map[string]func(*sysData) func() bool
@@ -98,6 +99,16 @@ var classTypes = [nctypes]*classData{
text: gtk_label_get_text,
},
c_listbox: &classData{
+ make: gListboxNewSingle,
+ makeAlt: gListboxNewMulti,
+ // TODO setText
+ text: gListboxText,
+ append: gListboxAppend,
+ insert: gListboxInsert,
+ selected: gListboxSelected,
+ selMulti: gListboxSelectedMulti,
+ smtexts: gListboxSelMultiTexts,
+ delete: gListboxDelete,
},
}
@@ -173,7 +184,9 @@ func (s *sysData) hide() error {
}
func (s *sysData) setText(text string) error {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].setText == nil { return nil }
+ if classTypes[s.ctype].setText == nil { // does not have concept of text
+ return nil
+ }
ret := make(chan struct{})
defer close(ret)
uitask <- func() {
@@ -185,7 +198,6 @@ if classTypes[s.ctype] == nil || classTypes[s.ctype].setText == nil { return nil
}
func (s *sysData) setRect(x int, y int, width int, height int) error {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
ret := make(chan struct{})
defer close(ret)
uitask <- func() {
@@ -207,7 +219,6 @@ func (s *sysData) isChecked() bool {
}
func (s *sysData) text() string {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { println(s.ctype,"unsupported text()"); return "" }
ret := make(chan string)
defer close(ret)
uitask <- func() {
@@ -217,7 +228,6 @@ if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { println(s.cty
}
func (s *sysData) append(what string) error {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
ret := make(chan struct{})
defer close(ret)
uitask <- func() {
@@ -229,7 +239,6 @@ if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
}
func (s *sysData) insertBefore(what string, before int) error {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
ret := make(chan struct{})
defer close(ret)
uitask <- func() {
@@ -241,7 +250,6 @@ if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
}
func (s *sysData) selectedIndex() int {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return -1 }
ret := make(chan int)
defer close(ret)
uitask <- func() {
@@ -251,13 +259,21 @@ if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return -1 }
}
func (s *sysData) selectedIndices() []int {
- // TODO
- return nil
+ ret := make(chan []int)
+ defer close(ret)
+ uitask <- func() {
+ ret <- classTypes[s.ctype].selMulti(s.widget)
+ }
+ return <-ret
}
func (s *sysData) selectedTexts() []string {
- // TODO
- return nil
+ ret := make(chan []string)
+ defer close(ret)
+ uitask <- func() {
+ ret <- classTypes[s.ctype].smtexts(s.widget)
+ }
+ return <-ret
}
func (s *sysData) setWindowSize(width int, height int) error {
@@ -272,7 +288,6 @@ func (s *sysData) setWindowSize(width int, height int) error {
}
func (s *sysData) delete(index int) error {
-if classTypes[s.ctype] == nil || classTypes[s.ctype].make == nil { return nil }
ret := make(chan struct{})
defer close(ret)
uitask <- func() {