unix: add uiTableSelection to get table selection

This commit is contained in:
Ben Campbell 2018-08-18 10:04:19 +12:00
parent 49f2095d94
commit c148ee79da
2 changed files with 79 additions and 0 deletions

23
ui.h
View File

@ -1458,6 +1458,29 @@ _UI_EXTERN void uiTableAppendButtonColumn(uiTable *t,
int buttonModelColumn, int buttonModelColumn,
int buttonClickableModelColumn); int buttonClickableModelColumn);
// uiTableOnSelectionChanged sets a callback to invoke upon changes
// in the set of selected items in the table.
_UI_EXTERN void uiTableOnSelectionChanged(uiTable *t, void (*f)(uiTable *t, void *data), void *data);
// uiTableSelection holds an array of row indexes for a table.
typedef struct uiTableSelection uiTableSelection;
struct uiTableSelection
{
int NumItems;
int* Items;
};
// uiTableCurrentSelection returns a uiTableSelection containing
// an array of all the selected rows in the table.
// If no rows are selected, a uiTableSelection will still be
// returned, with NumItems set to 0.
// The caller is responsible for calling uiFreeTableSelection()
// when finished with the uiTableSelection.
_UI_EXTERN uiTableSelection* uiTableCurrentSelection(uiTable* t);
// uiFreeTableSelection frees any memory allocated to a uiTableSelection
_UI_EXTERN void uiFreeTableSelection(uiTableSelection* sel);
// uiNewTable() creates a new uiTable with the specified parameters. // uiNewTable() creates a new uiTable with the specified parameters.
_UI_EXTERN uiTable *uiNewTable(uiTableParams *params); _UI_EXTERN uiTable *uiNewTable(uiTableParams *params);

View File

@ -511,6 +511,62 @@ void uiTableOnSelectionChanged(uiTable *t, void (*f)(uiTable *, void *), void *d
t->onSelectionChangedData = data; t->onSelectionChangedData = data;
} }
// internal implementation of uiTableSelection (growable, because we
// don't know the size of the selection in advance under Gtk+)
// So we have extra stuff hanging on to the end of the public
// uiTableSelection we return, but callers don't have to care.
// Yay C!
struct growableTableSelection
{
uiTableSelection sel;
int cap;
// TODO: could have an int here for single-selection case to avoid extra alloc...
};
static void collectSelection( GtkTreeModel *model,
GtkTreePath *path,
GtkTreeIter *iter,
gpointer data)
{
struct growableTableSelection* it = (struct growableTableSelection*)data;
int depth = gtk_tree_path_get_depth(path);
gint* indices = gtk_tree_path_get_indices(path);
if (depth < 1) {
return;
}
// append to collection
if (it->sel.NumItems == it->cap) {
// initial alloc or grow
if (it->cap == 0) {
it->cap = 16;
} else {
it->cap *= 2;
}
it->sel.Items = uiprivRealloc(it->sel.Items, sizeof(int) * it->cap, "int[]");
}
it->sel.Items[it->sel.NumItems++] = (int)indices[0];
}
uiTableSelection* uiTableCurrentSelection(uiTable* t)
{
struct growableTableSelection* g = uiprivAlloc(sizeof(struct growableTableSelection), "uiTableSelection");
g->sel.NumItems = 0;
g->sel.Items = NULL;
g->cap = 0;
gtk_tree_selection_selected_foreach( gtk_tree_view_get_selection(t->tv), collectSelection, (gpointer)g);
return (uiTableSelection*)g;
}
void uiFreeTableSelection(uiTableSelection* sel)
{
struct growableTableSelection* g = (struct growableTableSelection*)sel;
if (g->sel.Items) {
uiprivFree(g->sel.Items);
}
uiprivFree(g);
}
uiTable *uiNewTable(uiTableParams *p) uiTable *uiNewTable(uiTableParams *p)
{ {
uiTable *t; uiTable *t;