Added GTK+ listboxes... sort of. This whole thing is so broken it's funny.
This commit is contained in:
parent
919e89ca7e
commit
0856e953be
134
gtkcalls_unix.go
134
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)
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue