Hooked all the GTK+ Table stuff together and got it working. Woo!
This commit is contained in:
parent
f099d935ea
commit
abb77b7a5c
|
@ -34,5 +34,6 @@ struct goTableModelClass {
|
||||||
GObjectClass parent_class;
|
GObjectClass parent_class;
|
||||||
};
|
};
|
||||||
extern goTableModel *newTableModel(void *);
|
extern goTableModel *newTableModel(void *);
|
||||||
|
extern void tableUpdate(goTableModel *, gint, gint);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,13 +41,13 @@ static void goTableModel_dispose(GObject *obj)
|
||||||
G_OBJECT_CLASS(goTableModel_parent_class)->dispose(obj);
|
G_OBJECT_CLASS(goTableModel_parent_class)->dispose(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* and now for the interface function definitions */
|
|
||||||
|
|
||||||
static void goTableModel_finalize(GObject *obj)
|
static void goTableModel_finalize(GObject *obj)
|
||||||
{
|
{
|
||||||
G_OBJECT_CLASS(goTableModel_parent_class)->finalize(obj);
|
G_OBJECT_CLASS(goTableModel_parent_class)->finalize(obj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* and now for the interface function definitions */
|
||||||
|
|
||||||
static GtkTreeModelFlags goTableModel_get_flags(GtkTreeModel *model)
|
static GtkTreeModelFlags goTableModel_get_flags(GtkTreeModel *model)
|
||||||
{
|
{
|
||||||
return GTK_TREE_MODEL_LIST_ONLY;
|
return GTK_TREE_MODEL_LIST_ONLY;
|
||||||
|
@ -96,6 +96,9 @@ static void goTableModel_get_value(GtkTreeModel *model, GtkTreeIter *iter, gint
|
||||||
/* TODO what if iter is invalid? */
|
/* TODO what if iter is invalid? */
|
||||||
/* we (actually cgo) allocated str with malloc(), not g_malloc(), so let's free it explicitly and give the GValue a copy to be safe */
|
/* we (actually cgo) allocated str with malloc(), not g_malloc(), so let's free it explicitly and give the GValue a copy to be safe */
|
||||||
str = goTableModel_do_get_value(t->gotable, (gint) iter->user_data, column);
|
str = goTableModel_do_get_value(t->gotable, (gint) iter->user_data, column);
|
||||||
|
/* value is uninitialized */
|
||||||
|
/* TODO add support for multiple types */
|
||||||
|
g_value_init(value, G_TYPE_STRING);
|
||||||
g_value_set_string(value, str);
|
g_value_set_string(value, str);
|
||||||
free(str);
|
free(str);
|
||||||
}
|
}
|
||||||
|
@ -239,3 +242,38 @@ goTableModel *newTableModel(void *gotable)
|
||||||
{
|
{
|
||||||
return (goTableModel *) g_object_new(goTableModel_get_type(), "gotable", (gpointer) gotable, NULL);
|
return (goTableModel *) g_object_new(goTableModel_get_type(), "gotable", (gpointer) gotable, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* somewhat naive, but the only alternatives seem to be unloading/reloading the model (or the view!), which is bleh */
|
||||||
|
void tableUpdate(goTableModel *t, gint old, gint new)
|
||||||
|
{
|
||||||
|
gint i;
|
||||||
|
gint nUpdate;
|
||||||
|
GtkTreePath *path;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
iter.stamp = GOOD_STAMP;
|
||||||
|
/* first, append extra items */
|
||||||
|
if (old < new) {
|
||||||
|
for (i = old; i < new; i++) {
|
||||||
|
path = gtk_tree_path_new_from_indices(i, -1);
|
||||||
|
iter.user_data = (gpointer) i;
|
||||||
|
g_signal_emit_by_name(t, "row-inserted", path, &iter);
|
||||||
|
}
|
||||||
|
nUpdate = old;
|
||||||
|
} else
|
||||||
|
nUpdate = new;
|
||||||
|
/* next, update existing items */
|
||||||
|
for (i = 0; i < nUpdate; i++) {
|
||||||
|
path = gtk_tree_path_new_from_indices(i, -1);
|
||||||
|
iter.user_data = (gpointer) i;
|
||||||
|
g_signal_emit_by_name(t, "row-updated", path, &iter);
|
||||||
|
}
|
||||||
|
/* finally, remove deleted items */
|
||||||
|
if (old > new)
|
||||||
|
for (i = new; i < old; i++) {
|
||||||
|
/* note that we repeatedly remove the row at index new, as that changes with each removal; NOT i */
|
||||||
|
path = gtk_tree_path_new_from_indices(new, -1);
|
||||||
|
/* row-deleted has no iter */
|
||||||
|
g_signal_emit_by_name(t, "row-deleted", path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -13,6 +13,9 @@ import (
|
||||||
// #include "gtk_unix.h"
|
// #include "gtk_unix.h"
|
||||||
import "C"
|
import "C"
|
||||||
|
|
||||||
|
// TODOs
|
||||||
|
// - make column headers resizeable
|
||||||
|
|
||||||
type table struct {
|
type table struct {
|
||||||
*widgetbase
|
*widgetbase
|
||||||
*tablebase
|
*tablebase
|
||||||
|
@ -28,6 +31,7 @@ type table struct {
|
||||||
|
|
||||||
// stuff required by GtkTreeModel
|
// stuff required by GtkTreeModel
|
||||||
nColumns C.gint
|
nColumns C.gint
|
||||||
|
old C.gint
|
||||||
}
|
}
|
||||||
|
|
||||||
func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
func finishNewTable(b *tablebase, ty reflect.Type) Table {
|
||||||
|
@ -66,6 +70,11 @@ func (t *table) preferredSize(d *sizing) (width int, height int) {
|
||||||
return int(r.width), int(r.height)
|
return int(r.width), int(r.height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *table) Lock() {
|
||||||
|
t.tablebase.Lock()
|
||||||
|
d := reflect.Indirect(reflect.ValueOf(t.data))
|
||||||
|
t.old = C.gint(d.Len())
|
||||||
|
}
|
||||||
|
|
||||||
func (t *table) Unlock() {
|
func (t *table) Unlock() {
|
||||||
t.unlock()
|
t.unlock()
|
||||||
|
@ -73,7 +82,9 @@ func (t *table) Unlock() {
|
||||||
// not sure about this one...
|
// not sure about this one...
|
||||||
t.RLock()
|
t.RLock()
|
||||||
defer t.RUnlock()
|
defer t.RUnlock()
|
||||||
// TODO
|
d := reflect.Indirect(reflect.ValueOf(t.data))
|
||||||
|
new := C.gint(d.Len())
|
||||||
|
C.tableUpdate(t.model, t.old, new)
|
||||||
}
|
}
|
||||||
|
|
||||||
//export goTableModel_get_n_columns
|
//export goTableModel_get_n_columns
|
||||||
|
|
Loading…
Reference in New Issue