TreeView with CellRendererText extended as (new class) CellRendererWidget: can't see widget...
- From: bus dch byu net
- To: gtk-app-devel-list gnome org
- Subject: TreeView with CellRendererText extended as (new class) CellRendererWidget: can't see widget...
- Date: Fri, 19 Aug 2005 20:52:46 -0700
Hello! I'm pasting a test file in below. I am trying to embed widgets in the
TreeView. However, when I run the following file, I cannot see the widget.
I am using:
atk-1.10.1 glib-2.8.0 gtkmm-2.6.4 pango-1.10.0
cairo-0.9.2 glibmm-2.6.1 libiconv-1.9.2 pkg-config-0.19
freetype-2.1.10 gtk+-2.8.0 gettext-0.14.5 libsigc++-2.0.16
#include <gtk/gtk.h>
void maybe_update_text(GtkWidget * treeview, GtkWidget * widget,
const gchar * text)
{
}
typedef struct _GtkCellRendererWidget GtkCellRendererWidget;
struct _GtkCellRendererWidget
{
GtkCellRendererText parent;
GtkWidget * widget;
};
struct _GtkCellRendererWidgetClass
{
GtkCellRendererTextClass parent_class;
};
static GType cell_renderer_widget_type;
static gpointer cell_renderer_widget_parent_class;
#define GTK_CELL_RENDERER_WIDGET(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), \
cell_renderer_widget_type, \
GtkCellRendererWidget))
#define PROP_WIDGET 1
static void gtk_cell_renderer_widget_get_size(GtkCellRenderer * cr,
GtkWidget * treeview,
GdkRectangle * cell_area,
gint * x_offset, gint * y_offset,
gint * width, gint * height)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(cr);
if (crw->widget) {
GtkRequisition req;
gtk_widget_size_request(GTK_WIDGET(crw->widget), &req);
if (x_offset) *x_offset = 0;
if (y_offset) *y_offset = 0;
if (width) *width = req.width;
if (height) *height = req.height+50;
}
else GTK_CELL_RENDERER_CLASS(cell_renderer_widget_parent_class)->
get_size(cr, treeview, cell_area, x_offset, y_offset, width, height);
}
static void gtk_cell_renderer_widget_render(GtkCellRenderer * cr,
GdkWindow * bin_window,
GtkWidget * treeview,
GdkRectangle * background_area,
GdkRectangle * cell_area,
GdkRectangle * expose_area,
GtkCellRendererState flags)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(cr);
if (crw->widget && (crw->widget->allocation.x!=cell_area->x ||
crw->widget->allocation.y!=cell_area->y ||
crw->widget->allocation.width!=cell_area->width ||
crw->widget->allocation.height!=cell_area->height)) {
gtk_widget_size_allocate(crw->widget, cell_area);
}
maybe_update_text(treeview, crw->widget, GTK_CELL_RENDERER_TEXT(cr)->text);
GTK_CELL_RENDERER_CLASS(cell_renderer_widget_parent_class)->
render(cr, bin_window, treeview, background_area, cell_area, expose_area,
flags);
}
static GtkCellEditable * gtk_cell_renderer_widget_start_editing(
GtkCellRenderer * cr, GdkEvent * event,
GtkWidget * treeview, const gchar * path,
GdkRectangle * background_area,
GdkRectangle * cell_area, GtkCellRendererState flags)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(cr);
if (crw->widget) {
/* set focus to widget */
return 0;
}
return GTK_CELL_RENDERER_CLASS(cell_renderer_widget_parent_class)->
start_editing(cr, event, treeview, path, background_area, cell_area,
flags);
}
static void gtk_cell_renderer_widget_get_property(GObject * object,
guint paramid, GValue * value,
GParamSpec * pspec)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(object);
switch (paramid)
{
case PROP_WIDGET:
g_value_set_object(value, (GObject *) crw->widget);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, paramid, pspec);
break;
}
}
static void gtk_cell_renderer_widget_set_property(GObject * object,
guint paramid,
const GValue * value,
GParamSpec * pspec)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(object);
switch (paramid)
{
case PROP_WIDGET:
if (crw->widget) g_object_unref(G_OBJECT(crw->widget));
crw->widget = GTK_WIDGET(g_value_get_object(value));
if (crw->widget) g_object_ref(G_OBJECT(crw->widget));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID(object, paramid, pspec);
break;
}
}
static void gtk_cell_renderer_widget_destroy(GtkObject * object)
{
GtkCellRendererWidget * crw = GTK_CELL_RENDERER_WIDGET(object);
if (crw->widget) {
printf("cell_r_widg widg=%08x refcount=%u: about to unref\n",
(unsigned) crw->widget, G_OBJECT(crw->widget)->ref_count);
g_object_unref(G_OBJECT(crw->widget));
}
(* GTK_OBJECT_CLASS(cell_renderer_widget_parent_class)->destroy)(object);
}
static void gtk_cell_renderer_widget_class_init(
struct _GtkCellRendererWidgetClass * cl)
{
GObjectClass * object_class = G_OBJECT_CLASS(cl);
GtkObjectClass * gtk_object_class = GTK_OBJECT_CLASS(cl);
GtkCellRendererClass * cell_r_class = GTK_CELL_RENDERER_CLASS(cl);
cell_renderer_widget_parent_class = g_type_class_peek_parent(cl);
object_class->get_property = gtk_cell_renderer_widget_get_property;
object_class->set_property = gtk_cell_renderer_widget_set_property;
gtk_object_class->destroy = gtk_cell_renderer_widget_destroy;
cell_r_class->get_size = gtk_cell_renderer_widget_get_size;
cell_r_class->render = gtk_cell_renderer_widget_render;
cell_r_class->start_editing = gtk_cell_renderer_widget_start_editing;
g_object_class_install_property(object_class, PROP_WIDGET,
g_param_spec_object("widget", "Widget",
"Widget in cell",
GTK_TYPE_WIDGET,
G_PARAM_READWRITE |
G_PARAM_STATIC_NAME |
G_PARAM_STATIC_NICK |
G_PARAM_STATIC_BLURB));
}
static void gtk_cell_renderer_widget_init(GtkCellRendererWidget * crw)
{
crw->widget = 0;
}
GType gtk_cell_renderer_widget_register_type()
{
static const GTypeInfo renderer_widget_info =
{
sizeof(struct _GtkCellRendererWidgetClass),
0, /* base_init */
0, /* base_finalize */
(GClassInitFunc) gtk_cell_renderer_widget_class_init,
0, /* class_finalize */
0, /* class_data */
sizeof(GtkCellRendererWidget),
0, /* n_preallocs */
(GInstanceInitFunc) gtk_cell_renderer_widget_init,
};
return g_type_register_static(GTK_TYPE_CELL_RENDERER_TEXT,
"GtkCellRendererWidget",
&renderer_widget_info, 0);
}
GtkCellRenderer * gtk_cell_renderer_widget_new()
{
return g_object_new(cell_renderer_widget_type, 0);
}
GtkButton * the_button;
gboolean the_button_is_exposed(GtkWidget * widget, GdkEventExpose * event,
gpointer data)
{
printf("the_button_is_exposed\n");
return FALSE; /* propagate the event to other handlers */
}
gboolean is_treeview_row_a_separator(GtkTreeModel * model, GtkTreeIter * iter,
gpointer context)
{
gboolean is_separator;
gtk_tree_model_get(model, iter, 1, &is_separator, -1);
return is_separator;
}
void the_button_destroyed(GtkObject * obj, gpointer data)
{
if (obj!=GTK_OBJECT(the_button))
printf("obj=%08x the_button=%08x ???\n",
(unsigned) obj, (unsigned) the_button);
printf("the_button destroyed\n");
}
struct treeview_expose_data
{
GtkContainer * treeview;
GdkEventExpose * event;
};
gboolean treeview_expose_model_foreach(GtkTreeModel * model,
GtkTreePath * path, GtkTreeIter * iter,
gpointer data)
{
struct treeview_expose_data * p = (struct treeview_expose_data *) data;
GObject * widget;
gtk_tree_model_get(model, iter, 5, &widget, -1);
if (!widget) return FALSE; /* continue on foreach walk */
GdkWindow * tvw = gtk_tree_view_get_bin_window(GTK_TREE_VIEW(p->treeview));
GtkWidget * w = GTK_WIDGET(widget);
g_return_val_if_fail(!w->window || w->window==tvw, FALSE);
if (!w->window) {
printf("set parent of %08x\n", (unsigned) w);
gtk_widget_set_parent_window(w, tvw);
gtk_widget_set_parent(w, GTK_WIDGET(p->treeview));
/* gtk_widget_set_parent() does us a "favor" and does a g_object_ref() */
g_object_unref(widget);
gtk_widget_show(w);
gtk_widget_queue_resize(w);
}
gtk_container_propagate_expose(p->treeview, w, p->event);
g_object_unref(widget);
return FALSE; /* continue on foreach walk */
}
gboolean treeview_expose_model_widgets(GtkWidget * treeview,
GdkEventExpose * event, gpointer p)
{
/* attached to expose-event in treeview: propagate expose to all widgets */
struct treeview_expose_data data;
if (event->window != gtk_tree_view_get_bin_window(GTK_TREE_VIEW(treeview)))
return FALSE; /* propagate the event to other handlers */
data.treeview = GTK_CONTAINER(treeview);
data.event = event;
gtk_tree_model_foreach(gtk_tree_view_get_model(GTK_TREE_VIEW(treeview)),
treeview_expose_model_foreach, &data);
return FALSE; /* propagate the event to other handlers */
}
void treestore_set_widget(GtkTreeStore * tstore, GtkTreeIter * iter,
const char * label, GtkWidget * widget)
{
gtk_tree_store_set(tstore, iter, 0, label, 1, FALSE, 3, TRUE, 4, TRUE,
5, widget, -1);
gtk_object_sink(GTK_OBJECT(widget));
}
GtkCellRenderer * r2;
void test_treeview(GtkScrolledWindow * sw)
{
the_button = GTK_BUTTON(gtk_button_new_with_label("Test"));
/*gtk_widget_show(GTK_WIDGET(the_button));*/
printf("new the_button = %08x\n", (unsigned) the_button);
g_signal_connect(G_OBJECT(the_button), "destroy",
G_CALLBACK(the_button_destroyed), 0);
g_signal_connect(G_OBJECT(the_button), "expose-event",
G_CALLBACK(the_button_is_exposed), 0);
GtkTreeStore * tstore = gtk_tree_store_new(6,
G_TYPE_STRING, /* label */
G_TYPE_BOOLEAN, /* is_separator */
G_TYPE_STRING, /* contents */
G_TYPE_BOOLEAN, /* contents.visible */
G_TYPE_BOOLEAN, /* contents.editable */
G_TYPE_OBJECT /* contents.widget */);
GtkWidget * treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tstore));
g_signal_connect(G_OBJECT(treeview), "expose-event",
G_CALLBACK(treeview_expose_model_widgets), 0);
gtk_tree_view_set_row_separator_func(GTK_TREE_VIEW(treeview),
is_treeview_row_a_separator, 0, 0);
GtkCellRenderer * r1 = gtk_cell_renderer_text_new();
GtkTreeViewColumn * col1 = gtk_tree_view_column_new_with_attributes(
"Label", r1, "text", 0, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col1);
r2 = gtk_cell_renderer_widget_new();
GtkTreeViewColumn * col2 = gtk_tree_view_column_new_with_attributes(
"Contents", r2, "text", 2, "visible", 3,
"editable", 4, "widget", 5, NULL);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), col2);
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
gtk_container_add(GTK_CONTAINER(sw), treeview);
GtkTreeIter pi, ci, gi;
gtk_tree_store_append(tstore, &pi, 0);
gtk_tree_store_set(tstore, &pi, 0, "Parent 1", 1, FALSE,
2, "Value 1", 3, FALSE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 1.1", 1, FALSE,
2, "Value 1.1", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 1.2", 1, FALSE,
2, "Value 1.2", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 1.3", 1, FALSE,
2, "Value 1.3", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &pi, 0);
gtk_tree_store_set(tstore, &pi, 0, "Parent 2", 1, FALSE,
2, "Value 2", 3, FALSE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 2.1", 1, FALSE,
2, "Value 2.1", 3, FALSE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &gi, &ci);
gtk_tree_store_set(tstore, &gi, 0, "Grandchild 2.1.1", 1, FALSE,
2, "Value 2.1.1", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &gi, &ci);
treestore_set_widget(tstore, &gi, "Grandchild 2.1.2", GTK_WIDGET(the_button));
gtk_tree_store_append(tstore, &gi, &ci);
gtk_tree_store_set(tstore, &gi, 0, "Grandchild 2.1.3", 1, FALSE,
2, "Value 2.1.3", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 2.2", 1, FALSE,
2, "Value 2.2", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 2.3", 1, FALSE,
2, "Value 2.3", 3, TRUE, 4, TRUE, -1);
gtk_tree_view_expand_row(GTK_TREE_VIEW(treeview),
gtk_tree_model_get_path(GTK_TREE_MODEL(tstore), &pi),
TRUE /*open_all*/);
gtk_tree_store_append(tstore, &pi, 0);
gtk_tree_store_set(tstore, &pi, 0, "Separator", 1, TRUE,
2, "(separator)", 3, FALSE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &pi, 0);
gtk_tree_store_set(tstore, &pi, 0, "Parent 3", 1, FALSE,
2, "Value 3", 3, FALSE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 3.1", 1, FALSE,
2, "Value 3.1", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 3.2", 1, FALSE,
2, "Value 3.2", 3, TRUE, 4, TRUE, -1);
gtk_tree_store_append(tstore, &ci, &pi);
gtk_tree_store_set(tstore, &ci, 0, "Child 3.3", 1, FALSE,
2, "Value 3.3", 3, TRUE, 4, TRUE, -1);
g_object_unref(G_OBJECT(tstore));
}
int main(int argc, char ** argv)
{
gtk_init(&argc, &argv);
cell_renderer_widget_type = gtk_cell_renderer_widget_register_type();
GtkWidget * window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_default_size(GTK_WINDOW(window), 500, 300);
g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(gtk_main_quit), 0);
g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(gtk_main_quit),
0);
GtkWidget * sw = gtk_scrolled_window_new(0, 0);
test_treeview(GTK_SCROLLED_WINDOW(sw));
gtk_container_add(GTK_CONTAINER(window), sw);
gtk_widget_show_all(window);
gtk_main();
gtk_widget_destroy(sw);
return 0;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]