Converted column functions and editable handlers on GTK+.
This commit is contained in:
parent
75a5a050cb
commit
18d8a8fe22
298
unix/table.c
298
unix/table.c
|
@ -2,30 +2,6 @@
|
||||||
#include "uipriv_unix.h"
|
#include "uipriv_unix.h"
|
||||||
#include "table.h"
|
#include "table.h"
|
||||||
|
|
||||||
enum {
|
|
||||||
partText,
|
|
||||||
partImage,
|
|
||||||
partButton,
|
|
||||||
partCheckbox,
|
|
||||||
partProgressBar,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct tablePart {
|
|
||||||
int type;
|
|
||||||
int textColumn;
|
|
||||||
int imageColumn;
|
|
||||||
int valueColumn;
|
|
||||||
int colorColumn;
|
|
||||||
GtkCellRenderer *r;
|
|
||||||
uiTable *tv; // for pixbufs and background color
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiTableColumn {
|
|
||||||
GtkTreeViewColumn *c;
|
|
||||||
uiTable *tv; // for pixbufs and background color
|
|
||||||
GPtrArray *parts;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct uiTable {
|
struct uiTable {
|
||||||
uiUnixControl c;
|
uiUnixControl c;
|
||||||
GtkWidget *widget;
|
GtkWidget *widget;
|
||||||
|
@ -33,14 +9,13 @@ struct uiTable {
|
||||||
GtkScrolledWindow *sw;
|
GtkScrolledWindow *sw;
|
||||||
GtkWidget *treeWidget;
|
GtkWidget *treeWidget;
|
||||||
GtkTreeView *tv;
|
GtkTreeView *tv;
|
||||||
GPtrArray *columns;
|
|
||||||
uiTableModel *model;
|
uiTableModel *model;
|
||||||
int backgroundColumn;
|
int backgroundColumn;
|
||||||
};
|
};
|
||||||
|
|
||||||
// use the same size as GtkFileChooserWidget's treeview
|
// use the same size as GtkFileChooserWidget's treeview
|
||||||
// TODO refresh when icon theme changes
|
// TODO refresh when icon theme changes
|
||||||
// TODO doesn't work when scaled
|
// TODO doesn't work when scaled?
|
||||||
// TODO is this even necessary?
|
// TODO is this even necessary?
|
||||||
static void setImageSize(GtkCellRenderer *r)
|
static void setImageSize(GtkCellRenderer *r)
|
||||||
{
|
{
|
||||||
|
@ -57,12 +32,12 @@ static void setImageSize(GtkCellRenderer *r)
|
||||||
2 * ypad + size);
|
2 * ypad + size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void applyColor(GtkTreeModel *mm, GtkTreeIter *iter, int modelColumn, GtkCellRenderer *r, const char *prop, const char *propSet)
|
static void applyColor(GtkTreeModel *m, GtkTreeIter *iter, int modelColumn, GtkCellRenderer *r, const char *prop, const char *propSet)
|
||||||
{
|
{
|
||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
GdkRGBA *rgba;
|
GdkRGBA *rgba;
|
||||||
|
|
||||||
gtk_tree_model_get_value(mm, iter, modelColumn, &value);
|
gtk_tree_model_get_value(m, iter, modelColumn, &value);
|
||||||
rgba = (GdkRGBA *) g_value_get_boxed(&value);
|
rgba = (GdkRGBA *) g_value_get_boxed(&value);
|
||||||
if (rgba != NULL)
|
if (rgba != NULL)
|
||||||
g_object_set(r, prop, rgba, NULL);
|
g_object_set(r, prop, rgba, NULL);
|
||||||
|
@ -71,76 +46,217 @@ static void applyColor(GtkTreeModel *mm, GtkTreeIter *iter, int modelColumn, Gtk
|
||||||
g_value_unset(&value);
|
g_value_unset(&value);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *mm, GtkTreeIter *iter, gpointer data)
|
static void setEditable(uiTableModel *m, GtkTreeIter *iter, int modelColumn, GtkCellRenderer *r, const char *prop)
|
||||||
{
|
{
|
||||||
struct tablePart *part = (struct tablePart *) data;
|
uiTableData *data;
|
||||||
GValue value = G_VALUE_INIT;
|
GValue value = G_VALUE_INIT;
|
||||||
const gchar *str;
|
int value;
|
||||||
uiImage *img;
|
gboolean editable;
|
||||||
int pval;
|
|
||||||
|
|
||||||
switch (part->type) {
|
switch (modelColumn) {
|
||||||
case partText:
|
case uiTableModelColumnNeverEditable:
|
||||||
gtk_tree_model_get_value(mm, iter, part->textColumn, &value);
|
editable = FALSE;
|
||||||
str = g_value_get_string(&value);
|
|
||||||
g_object_set(r, "text", str, NULL);
|
|
||||||
if (part->colorColumn != -1)
|
|
||||||
applyColor(mm, iter,
|
|
||||||
part->colorColumn,
|
|
||||||
r, "foreground-rgba", "foreground-set");
|
|
||||||
break;
|
break;
|
||||||
case partImage:
|
case uiTableModelColumnAlwaysEditable:
|
||||||
//TODO setImageSize(r);
|
editable = TRUE;
|
||||||
gtk_tree_model_get_value(mm, iter, part->imageColumn, &value);
|
|
||||||
img = (uiImage *) g_value_get_pointer(&value);
|
|
||||||
g_object_set(r, "surface",
|
|
||||||
uiprivImageAppropriateSurface(img, part->tv->treeWidget),
|
|
||||||
NULL);
|
|
||||||
break;
|
|
||||||
case partButton:
|
|
||||||
gtk_tree_model_get_value(mm, iter, part->textColumn, &value);
|
|
||||||
str = g_value_get_string(&value);
|
|
||||||
g_object_set(r, "text", str, NULL);
|
|
||||||
break;
|
|
||||||
case partCheckbox:
|
|
||||||
gtk_tree_model_get_value(mm, iter, part->valueColumn, &value);
|
|
||||||
g_object_set(r, "active", g_value_get_int(&value) != 0, NULL);
|
|
||||||
break;
|
|
||||||
case partProgressBar:
|
|
||||||
gtk_tree_model_get_value(mm, iter, part->valueColumn, &value);
|
|
||||||
pval = g_value_get_int(&value);
|
|
||||||
if (pval == -1) {
|
|
||||||
// TODO
|
|
||||||
} else
|
|
||||||
g_object_set(r,
|
|
||||||
"pulse", -1,
|
|
||||||
"value", pval,
|
|
||||||
NULL);
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
gtk_tree_model_get_value(m, iter, p->editableColumn, &value);
|
||||||
|
editable = gtk_value_get_int(&value) != 0;
|
||||||
|
g_value_unset(&value);
|
||||||
}
|
}
|
||||||
g_value_unset(&value);
|
g_object_set(r, "editable", editable, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (part->tv->backgroundColumn != -1)
|
static void applyBackgroundColor(uiTable *t, GtkTreeModel *m, GtkTreeIter *iter, GtkCellRenderer *r)
|
||||||
applyColor(mm, iter,
|
{
|
||||||
part->tv->backgroundColumn,
|
if (t->backgroundColumn != -1)
|
||||||
|
applyColor(m, iter, t->backgroundColumn,
|
||||||
r, "cell-background-rgba", "cell-background-set");
|
r, "cell-background-rgba", "cell-background-set");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void onEdited(struct tablePart *part, int column, const char *pathstr, const void *data)
|
static void onEdited(uiTableModel *m, int column, const char *pathstr, const uiTableData *data, GtkTreeIter *iter)
|
||||||
{
|
{
|
||||||
GtkTreePath *path;
|
GtkTreePath *path;
|
||||||
int row;
|
int row;
|
||||||
uiTableModel *m;
|
|
||||||
|
|
||||||
path = gtk_tree_path_new_from_string(pathstr);
|
path = gtk_tree_path_new_from_string(pathstr);
|
||||||
row = gtk_tree_path_get_indices(path)[0];
|
row = gtk_tree_path_get_indices(path)[0];
|
||||||
|
if (iter != NULL)
|
||||||
|
gtk_tree_model_convert_path_to_iter(m, path, iter);
|
||||||
gtk_tree_path_free(path);
|
gtk_tree_path_free(path);
|
||||||
m = part->tv->model;
|
|
||||||
(*(m->mh->SetCellValue))(m->mh, m, row, column, data);
|
(*(m->mh->SetCellValue))(m->mh, m, row, column, data);
|
||||||
// and update
|
|
||||||
uiTableModelRowChanged(m, row);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO deduplicate this between platforms
|
||||||
|
static uiTableTextColumnOptionalParams defaultTextColumnOptionalParams = {
|
||||||
|
.ColorModelColumn = -1,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct textColumnParams {
|
||||||
|
uiTable *t;
|
||||||
|
uiTableModel *m;
|
||||||
|
int modelColumn;
|
||||||
|
int editableColumn;
|
||||||
|
uiTableTextColumnOptionalParams params;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void textColumnDataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *m, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
struct textColumnParams *p = (struct textColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
const gchar *str;
|
||||||
|
gboolean editable;
|
||||||
|
|
||||||
|
gtk_tree_model_get_value(m, iter, p->modelColumn, &value);
|
||||||
|
str = g_value_get_string(&value);
|
||||||
|
g_object_set(r, "text", str, NULL);
|
||||||
|
g_value_unset(&value);
|
||||||
|
|
||||||
|
setEditable(m, iter, p->editableColumn, r, "editable");
|
||||||
|
|
||||||
|
if (p->params.ColorModelColumn != -1)
|
||||||
|
applyColor(m, iter, p->params.ColorModelColumn,
|
||||||
|
r, "foreground-rgba", "foreground-set");
|
||||||
|
|
||||||
|
applyBackgroundColor(p->t, m, iter, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void textColumnEdited(GtkCellRendererText *renderer, gchar *path, gchar *newText, gpointer data)
|
||||||
|
{
|
||||||
|
struct textColumnParams *p = (struct textColumnParams *) data;
|
||||||
|
uiTableData *data;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
data = uiNewTableDataString(newText);
|
||||||
|
onEdited(p->m, p->textColumn, path, data, &iter);
|
||||||
|
uiFreeData(data);
|
||||||
|
// and update the column TODO copy comment here
|
||||||
|
textColumnDataFunc(NULL, r, GTK_TREE_MODEL(p->m), &iter, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct imageColumnParams {
|
||||||
|
uiTable *t;
|
||||||
|
int modelColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void imageColumnDataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *m, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
struct imageColumnParams *p = (struct imageColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
uiImage *img;
|
||||||
|
|
||||||
|
//TODO setImageSize(r);
|
||||||
|
gtk_tree_model_get_value(m, iter, p->modelColumn, &value);
|
||||||
|
img = (uiImage *) g_value_get_pointer(&value);
|
||||||
|
g_object_set(r, "surface",
|
||||||
|
uiprivImageAppropriateSurface(img, p->t->treeWidget),
|
||||||
|
NULL);
|
||||||
|
g_value_unset(&value);
|
||||||
|
|
||||||
|
applyBackgroundColor(p->t, m, iter, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct checkboxColumnParams {
|
||||||
|
uiTable *t;
|
||||||
|
uiTableModel *m;
|
||||||
|
int modelColumn;
|
||||||
|
int editableColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void checkboxColumnDataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *m, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
struct checkboxColumnParams *p = (struct checkboxColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
gboolean active;
|
||||||
|
|
||||||
|
gtk_tree_model_get_value(m, iter, p->modelColumn, &value);
|
||||||
|
active = g_value_get_int(&value) != 0;
|
||||||
|
g_object_set(r, "active", active, NULL);
|
||||||
|
g_value_unset(&value);
|
||||||
|
|
||||||
|
setEditable(m, iter, p->editableColumn, r, "activatable");
|
||||||
|
|
||||||
|
applyBackgroundColor(p->t, m, iter, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void checkboxColumnToggled(GtkCellRendererToggle *r, gchar *pathstr, gpointer data)
|
||||||
|
{
|
||||||
|
struct checkboxColumnParams *p = (struct checkboxColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
int v;
|
||||||
|
uiTableData *data;
|
||||||
|
GtkTreeIter iter;
|
||||||
|
|
||||||
|
gtk_tree_model_get_value(p->m, iter, p->modelColumn, &value);
|
||||||
|
v = g_value_get_int(&value);
|
||||||
|
g_value_unset(&value);
|
||||||
|
data = uiNewTableDataInt(!v);
|
||||||
|
onEdited(p->m, p->modelColumn, path, data, &iter);
|
||||||
|
uiFreeData(data);
|
||||||
|
// and update the column TODO copy comment here
|
||||||
|
// TODO avoid fetching the model data twice
|
||||||
|
checkboxColumnDataFunc(NULL, r, GTK_TREE_MODEL(p->m), &iter, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct progressBarColumnParams {
|
||||||
|
uiTable *t;
|
||||||
|
int modelColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void progressBarDataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *m, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
struct progressBarColumnParams *p = (struct progressBarColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
int pval;
|
||||||
|
|
||||||
|
gtk_tree_model_get_value(m, iter, p->modelColumn, &value);
|
||||||
|
pval = g_value_get_int(&value);
|
||||||
|
if (pval == -1) {
|
||||||
|
// TODO
|
||||||
|
} else
|
||||||
|
g_object_set(r,
|
||||||
|
"pulse", -1,
|
||||||
|
"value", pval,
|
||||||
|
NULL);
|
||||||
|
g_value_unset(&value);
|
||||||
|
|
||||||
|
applyBackgroundColor(p->t, m, iter, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct buttonColumnParams {
|
||||||
|
uiTable *t;
|
||||||
|
uiTableModel *m;
|
||||||
|
int modelColumn;
|
||||||
|
int clickableColumn;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void buttonDataFunc(GtkTreeViewColumn *c, GtkCellRenderer *r, GtkTreeModel *m, GtkTreeIter *iter, gpointer data)
|
||||||
|
{
|
||||||
|
struct buttonColumnParams *p = (struct buttonColumnParams *) data;
|
||||||
|
GValue value = G_VALUE_INIT;
|
||||||
|
const gchar *str;
|
||||||
|
gboolean clickable;
|
||||||
|
|
||||||
|
gtk_tree_model_get_value(m, iter, p->modelColumn, &value);
|
||||||
|
str = g_value_get_string(&value);
|
||||||
|
g_object_set(r, "text", str, NULL);
|
||||||
|
g_value_unset(&value);
|
||||||
|
|
||||||
|
setEditable(m, iter, p->clickableColumn, r, "clickable");
|
||||||
|
|
||||||
|
applyBackgroundColor(p->t, m, iter, r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void buttonColumnClicked(uiprivCellRendererButton *r, gchar *pathstr, gpointer data)
|
||||||
|
{
|
||||||
|
struct buttonColumnParams *p = (struct buttonColumnParams *) data;
|
||||||
|
|
||||||
|
onEdited(p->m, p->modelColumn, path, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
=================== TODOTODO
|
||||||
|
|
||||||
static void appendPart(uiTableColumn *c, struct tablePart *part, GtkCellRenderer *r, int expand)
|
static void appendPart(uiTableColumn *c, struct tablePart *part, GtkCellRenderer *r, int expand)
|
||||||
{
|
{
|
||||||
part->r = r;
|
part->r = r;
|
||||||
|
@ -149,13 +265,6 @@ static void appendPart(uiTableColumn *c, struct tablePart *part, GtkCellRenderer
|
||||||
g_ptr_array_add(c->parts, part);
|
g_ptr_array_add(c->parts, part);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void textEdited(GtkCellRendererText *renderer, gchar *path, gchar *newText, gpointer data)
|
|
||||||
{
|
|
||||||
struct tablePart *part = (struct tablePart *) data;
|
|
||||||
|
|
||||||
onEdited(part, part->textColumn, path, newText);
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTableColumnAppendTextPart(uiTableColumn *c, int modelColumn, int expand)
|
void uiTableColumnAppendTextPart(uiTableColumn *c, int modelColumn, int expand)
|
||||||
{
|
{
|
||||||
struct tablePart *part;
|
struct tablePart *part;
|
||||||
|
@ -212,25 +321,6 @@ void uiTableColumnAppendButtonPart(uiTableColumn *c, int modelColumn, int expand
|
||||||
appendPart(c, part, r, expand);
|
appendPart(c, part, r, expand);
|
||||||
}
|
}
|
||||||
|
|
||||||
// yes, we need to do all this twice :|
|
|
||||||
static void checkboxToggled(GtkCellRendererToggle *r, gchar *pathstr, gpointer data)
|
|
||||||
{
|
|
||||||
struct tablePart *part = (struct tablePart *) data;
|
|
||||||
GtkTreePath *path;
|
|
||||||
int row;
|
|
||||||
uiTableModel *m;
|
|
||||||
void *value;
|
|
||||||
int intval;
|
|
||||||
|
|
||||||
path = gtk_tree_path_new_from_string(pathstr);
|
|
||||||
row = gtk_tree_path_get_indices(path)[0];
|
|
||||||
gtk_tree_path_free(path);
|
|
||||||
m = part->tv->model;
|
|
||||||
value = (*(m->mh->CellValue))(m->mh, m, row, part->valueColumn);
|
|
||||||
intval = !uiTableModelTakeInt(value);
|
|
||||||
onEdited(part, part->valueColumn, pathstr, uiTableModelGiveInt(intval));
|
|
||||||
}
|
|
||||||
|
|
||||||
void uiTableColumnAppendCheckboxPart(uiTableColumn *c, int modelColumn, int expand)
|
void uiTableColumnAppendCheckboxPart(uiTableColumn *c, int modelColumn, int expand)
|
||||||
{
|
{
|
||||||
struct tablePart *part;
|
struct tablePart *part;
|
||||||
|
|
Loading…
Reference in New Issue