From 38666b406fe8b2f08e0d67014daea951c6efea73 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Fri, 12 Nov 2010 19:25:07 +0900 Subject: [PATCH] Ironed out the kinks in editing apis for GtkCellArea - Added gtk_cell_area_aligned_cell_area() to get the aligned internal area use by a cell (for focus painting and for event areas). - Provide the event area in "editing-started" signal - Fire "remove-editable" when editing is canceled by the user, an implementing layouting widget need only catch "editing-started" and "remove-editable" now. - CellAreaScaffold/testcellarea now edit textrenderers. --- gtk/gtkcellarea.c | 96 ++++++++++++++++---- gtk/gtkcellarea.h | 10 ++- gtk/gtkcellareabox.c | 65 ++++---------- gtk/gtkmarshalers.list | 1 + tests/cellareascaffold.c | 187 ++++++++++++++++++++++++++++++++------- tests/cellareascaffold.h | 4 +- tests/testcellarea.c | 23 ++++- 7 files changed, 290 insertions(+), 96 deletions(-) diff --git a/gtk/gtkcellarea.c b/gtk/gtkcellarea.c index 95eca930e7..7427254daa 100644 --- a/gtk/gtkcellarea.c +++ b/gtk/gtkcellarea.c @@ -132,7 +132,8 @@ static gint cell_attribute_find (CellAttribute *cell_attribut /* Internal signal emissions */ static void gtk_cell_area_editing_started (GtkCellArea *area, GtkCellRenderer *renderer, - GtkCellEditable *editable); + GtkCellEditable *editable, + GdkRectangle *cell_area); static void gtk_cell_area_editing_canceled (GtkCellArea *area, GtkCellRenderer *renderer); static void gtk_cell_area_editing_done (GtkCellArea *area, @@ -292,10 +293,11 @@ gtk_cell_area_class_init (GtkCellAreaClass *class) G_SIGNAL_RUN_FIRST, 0, /* No class closure here */ NULL, NULL, - _gtk_marshal_VOID__OBJECT_OBJECT_STRING, - G_TYPE_NONE, 3, + _gtk_marshal_VOID__OBJECT_OBJECT_BOXED_STRING, + G_TYPE_NONE, 4, GTK_TYPE_CELL_RENDERER, GTK_TYPE_CELL_EDITABLE, + GDK_TYPE_RECTANGLE, G_TYPE_STRING); cell_area_signals[SIGNAL_EDITING_CANCELED] = @@ -2079,10 +2081,11 @@ gtk_cell_area_get_focus_from_sibling (GtkCellArea *area, static void gtk_cell_area_editing_started (GtkCellArea *area, GtkCellRenderer *renderer, - GtkCellEditable *editable) + GtkCellEditable *editable, + GdkRectangle *cell_area) { g_signal_emit (area, cell_area_signals[SIGNAL_EDITING_STARTED], 0, - renderer, editable, area->priv->current_path); + renderer, editable, cell_area, area->priv->current_path); } static void @@ -2276,14 +2279,18 @@ gtk_cell_area_activate_cell (GtkCellArea *area, if (editable_widget != NULL) { + GdkRectangle edit_area; + g_return_val_if_fail (GTK_IS_CELL_EDITABLE (editable_widget), FALSE); gtk_cell_area_set_edited_cell (area, renderer); gtk_cell_area_set_edit_widget (area, editable_widget); + + gtk_cell_area_aligned_cell_area (area, widget, renderer, &inner_area, &edit_area); /* Signal that editing started so that callers can get * a handle on the editable_widget */ - gtk_cell_area_editing_started (area, priv->focus_cell, editable_widget); + gtk_cell_area_editing_started (area, priv->focus_cell, editable_widget, &edit_area); return TRUE; } @@ -2304,9 +2311,12 @@ gtk_cell_area_stop_editing (GtkCellArea *area, if (priv->edited_cell) { + GtkCellEditable *edit_widget = g_object_ref (priv->edit_widget); + GtkCellRenderer *edit_cell = g_object_ref (priv->edited_cell); + /* Stop editing of the cell renderer */ gtk_cell_renderer_stop_editing (priv->edited_cell, canceled); - + /* Signal that editing has been canceled */ if (canceled) gtk_cell_area_editing_canceled (area, priv->edited_cell); @@ -2314,6 +2324,13 @@ gtk_cell_area_stop_editing (GtkCellArea *area, /* Remove any references to the editable widget */ gtk_cell_area_set_edited_cell (area, NULL); gtk_cell_area_set_edit_widget (area, NULL); + + /* Send the remove-widget signal explicitly (this is done after setting + * the edit cell/widget NULL to avoid feedback) + */ + gtk_cell_area_remove_editable (area, edit_cell, edit_widget); + g_object_unref (edit_cell); + g_object_unref (edit_widget); } } @@ -2426,23 +2443,72 @@ gtk_cell_area_set_cell_margin_bottom (GtkCellArea *area, void gtk_cell_area_inner_cell_area (GtkCellArea *area, - const GdkRectangle *background_area, - GdkRectangle *cell_area) + const GdkRectangle *cell_area, + GdkRectangle *inner_area) { GtkCellAreaPrivate *priv; g_return_if_fail (GTK_IS_CELL_AREA (area)); - g_return_if_fail (background_area != NULL); g_return_if_fail (cell_area != NULL); + g_return_if_fail (inner_area != NULL); priv = area->priv; - *cell_area = *background_area; + *inner_area = *cell_area; - cell_area->x += priv->cell_border.left; - cell_area->width -= (priv->cell_border.left + priv->cell_border.right); - cell_area->y += priv->cell_border.top; - cell_area->height -= (priv->cell_border.top + priv->cell_border.bottom); + inner_area->x += priv->cell_border.left; + inner_area->width -= (priv->cell_border.left + priv->cell_border.right); + inner_area->y += priv->cell_border.top; + inner_area->height -= (priv->cell_border.top + priv->cell_border.bottom); +} + +void +gtk_cell_area_aligned_cell_area (GtkCellArea *area, + GtkWidget *widget, + GtkCellRenderer *renderer, + const GdkRectangle *cell_area, + GdkRectangle *aligned_area) +{ + GtkCellAreaPrivate *priv; + gint opposite_size, x_offset, y_offset; + + g_return_if_fail (GTK_IS_CELL_AREA (area)); + g_return_if_fail (GTK_IS_CELL_RENDERER (renderer)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (cell_area != NULL); + g_return_if_fail (aligned_area != NULL); + + priv = area->priv; + + *aligned_area = *cell_area; + + /* Trim up the aligned size */ + if (gtk_cell_renderer_get_request_mode (renderer) == GTK_SIZE_REQUEST_HEIGHT_FOR_WIDTH) + { + gtk_cell_renderer_get_preferred_height_for_width (renderer, widget, + aligned_area->width, + NULL, &opposite_size); + + aligned_area->height = MIN (opposite_size, aligned_area->height); + } + else + { + gtk_cell_renderer_get_preferred_width_for_height (renderer, widget, + aligned_area->height, + NULL, &opposite_size); + + aligned_area->width = MIN (opposite_size, aligned_area->width); + } + + /* offset the cell position */ + _gtk_cell_renderer_calc_offset (renderer, cell_area, + gtk_widget_get_direction (widget), + aligned_area->width, + aligned_area->height, + &x_offset, &y_offset); + + aligned_area->x += x_offset; + aligned_area->y += y_offset; } void diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h index 66884519be..2ef917805f 100644 --- a/gtk/gtkcellarea.h +++ b/gtk/gtkcellarea.h @@ -343,7 +343,15 @@ void gtk_cell_area_set_cell_margin_bottom (GtkCellArea /* Distinguish the inner cell area from the whole requested area including margins */ void gtk_cell_area_inner_cell_area (GtkCellArea *area, const GdkRectangle *cell_area, - GdkRectangle *inner_cell_area); + GdkRectangle *inner_area); + +/* Aligns a cell renderer into cell_area by requesting it's size ... used for focus and cell edit areas */ +void gtk_cell_area_aligned_cell_area (GtkCellArea *area, + GtkWidget *widget, + GtkCellRenderer *renderer, + const GdkRectangle *cell_area, + GdkRectangle *aligned_area); + /* Request the size of a cell while respecting the cell margins (requests are margin inclusive) */ void gtk_cell_area_request_renderer (GtkCellArea *area, diff --git a/gtk/gtkcellareabox.c b/gtk/gtkcellareabox.c index 7fbcf9ba52..a6f6acdd08 100644 --- a/gtk/gtkcellareabox.c +++ b/gtk/gtkcellareabox.c @@ -903,11 +903,8 @@ gtk_cell_area_box_event (GtkCellArea *area, GtkCellAreaBoxIter *box_iter = GTK_CELL_AREA_BOX_ITER (iter); GSList *allocated_cells, *l; GdkRectangle cell_background, inner_area; - GtkAllocation allocation; gint event_x, event_y; - gtk_widget_get_allocation (widget, &allocation); - /* We may need some semantics to tell us the offset of the event * window we are handling events for (i.e. GtkTreeView has a bin_window) */ event_x = button_event->x; @@ -1025,6 +1022,7 @@ gtk_cell_area_box_render (GtkCellArea *area, { AllocatedCell *cell = l->data; GtkCellRendererState cell_fields = 0; + GdkRectangle render_background; if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { @@ -1041,37 +1039,39 @@ gtk_cell_area_box_render (GtkCellArea *area, */ gtk_cell_area_inner_cell_area (area, &cell_background, &inner_area); - /* Here after getting the inner area of the cell background, - * add portions of the background area to the cell background */ + /* Add portions of the background_area to the cell_background + * to create the render_background */ + render_background = cell_background; + if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) { if (l == allocated_cells) { - cell_background.width += cell_background.x - background_area->x; - cell_background.x = background_area->x; + render_background.width += render_background.x - background_area->x; + render_background.x = background_area->x; } if (l->next == NULL) - cell_background.width = - background_area->width - (cell_background.x - background_area->x); + render_background.width = + background_area->width - (render_background.x - background_area->x); - cell_background.y = background_area->y; - cell_background.height = background_area->height; + render_background.y = background_area->y; + render_background.height = background_area->height; } else { if (l == allocated_cells) { - cell_background.height += cell_background.y - background_area->y; - cell_background.y = background_area->y; + render_background.height += render_background.y - background_area->y; + render_background.y = background_area->y; } if (l->next == NULL) - cell_background.height = - background_area->height - (cell_background.y - background_area->y); + render_background.height = + background_area->height - (render_background.y - background_area->y); - cell_background.x = background_area->x; - cell_background.width = background_area->width; + render_background.x = background_area->x; + render_background.width = background_area->width; } if (focus_cell && @@ -1083,35 +1083,8 @@ gtk_cell_area_box_render (GtkCellArea *area, if (paint_focus) { GdkRectangle cell_focus; - gint opposite_size, x_offset, y_offset; - cell_focus = inner_area; - - /* Trim up the focus size */ - if (priv->orientation == GTK_ORIENTATION_HORIZONTAL) - { - gtk_cell_renderer_get_preferred_height_for_width (cell->renderer, widget, - cell_focus.width, - NULL, &opposite_size); - - cell_focus.height = MIN (opposite_size, cell_focus.height); - } - else - { - gtk_cell_renderer_get_preferred_width_for_height (cell->renderer, widget, - cell_focus.height, - NULL, &opposite_size); - - cell_focus.width = MIN (opposite_size, cell_focus.width); - } - - /* offset the cell position */ - _gtk_cell_renderer_calc_offset (cell->renderer, &inner_area, GTK_TEXT_DIR_LTR, - cell_focus.width, cell_focus.height, - &x_offset, &y_offset); - - cell_focus.x += x_offset; - cell_focus.y += y_offset; + gtk_cell_area_aligned_cell_area (area, widget, cell->renderer, &inner_area, &cell_focus); /* Accumulate the focus rectangle for all focus siblings */ if (first_focus_cell) @@ -1127,7 +1100,7 @@ gtk_cell_area_box_render (GtkCellArea *area, /* We have to do some per-cell considerations for the 'flags' * for focus handling */ gtk_cell_renderer_render (cell->renderer, cr, widget, - &cell_background, &inner_area, + &render_background, &inner_area, flags | cell_fields); } diff --git a/gtk/gtkmarshalers.list b/gtk/gtkmarshalers.list index 9332f3a172..248bd6e059 100644 --- a/gtk/gtkmarshalers.list +++ b/gtk/gtkmarshalers.list @@ -92,6 +92,7 @@ VOID:OBJECT,UINT,FLAGS VOID:OBJECT,STRING VOID:OBJECT,OBJECT,STRING VOID:OBJECT,OBJECT,OBJECT +VOID:OBJECT,OBJECT,BOXED,STRING VOID:POINTER VOID:POINTER,INT VOID:POINTER,BOOLEAN diff --git a/tests/cellareascaffold.c b/tests/cellareascaffold.c index 3e3787ab4d..66750b09c9 100644 --- a/tests/cellareascaffold.c +++ b/tests/cellareascaffold.c @@ -64,6 +64,19 @@ static gint cell_area_scaffold_focus (GtkWidget static gboolean cell_area_scaffold_button_press (GtkWidget *widget, GdkEventButton *event); +/* GtkContainerClass */ +static void cell_area_scaffold_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data); +static void cell_area_scaffold_remove (GtkContainer *container, + GtkWidget *child); +static void cell_area_scaffold_put_edit_widget (CellAreaScaffold *scaffold, + GtkWidget *edit_widget, + gint x, + gint y, + gint width, + gint height); /* CellAreaScaffoldClass */ static void cell_area_scaffold_activate (CellAreaScaffold *scaffold); @@ -76,22 +89,32 @@ static void focus_changed_cb (GtkCellArea GtkCellRenderer *renderer, const gchar *path, CellAreaScaffold *scaffold); +static void editing_started_cb (GtkCellArea *area, + GtkCellRenderer *renderer, + GtkCellEditable *edit_widget, + GdkRectangle *cell_area, + const gchar *path, + CellAreaScaffold *scaffold); +static void remove_editable_cb (GtkCellArea *area, + GtkCellRenderer *renderer, + GtkCellEditable *edit_widget, + CellAreaScaffold *scaffold); static void row_changed_cb (GtkTreeModel *model, GtkTreePath *path, GtkTreeIter *iter, CellAreaScaffold *scaffold); -static void row_inserted_cb (GtkTreeModel *model, - GtkTreePath *path, - GtkTreeIter *iter, - CellAreaScaffold *scaffold); -static void row_deleted_cb (GtkTreeModel *model, - GtkTreePath *path, - CellAreaScaffold *scaffold); -static void rows_reordered_cb (GtkTreeModel *model, - GtkTreePath *parent, - GtkTreeIter *iter, - gint *new_order, - CellAreaScaffold *scaffold); +static void row_inserted_cb (GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + CellAreaScaffold *scaffold); +static void row_deleted_cb (GtkTreeModel *model, + GtkTreePath *path, + CellAreaScaffold *scaffold); +static void rows_reordered_cb (GtkTreeModel *model, + GtkTreePath *parent, + GtkTreeIter *iter, + gint *new_order, + CellAreaScaffold *scaffold); typedef struct { gint size; /* The size of the row in the scaffold's opposing orientation */ @@ -124,7 +147,11 @@ struct _CellAreaScaffoldPrivate { * we need to queue a redraw */ gulong size_changed_id; - + /* Currently edited widget */ + GtkWidget *edit_widget; + GdkRectangle edit_rect; + gulong editing_started_id; + gulong remove_editable_id; }; enum { @@ -149,7 +176,7 @@ static guint scaffold_signals[N_SIGNALS] = { 0 }; (dir) == GTK_DIR_LEFT ? "left" : \ (dir) == GTK_DIR_RIGHT ? "right" : "invalid") -G_DEFINE_TYPE_WITH_CODE (CellAreaScaffold, cell_area_scaffold, GTK_TYPE_WIDGET, +G_DEFINE_TYPE_WITH_CODE (CellAreaScaffold, cell_area_scaffold, GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (GTK_TYPE_ORIENTABLE, NULL)); @@ -171,28 +198,39 @@ cell_area_scaffold_init (CellAreaScaffold *scaffold) gtk_widget_set_has_window (GTK_WIDGET (scaffold), FALSE); gtk_widget_set_can_focus (GTK_WIDGET (scaffold), TRUE); + priv->size_changed_id = + g_signal_connect (priv->iter, "notify", + G_CALLBACK (size_changed_cb), scaffold); + priv->focus_changed_id = g_signal_connect (priv->area, "focus-changed", G_CALLBACK (focus_changed_cb), scaffold); - priv->size_changed_id = - g_signal_connect (priv->iter, "notify", - G_CALLBACK (size_changed_cb), scaffold); + priv->editing_started_id = + g_signal_connect (priv->area, "editing-started", + G_CALLBACK (editing_started_cb), scaffold); + + priv->remove_editable_id = + g_signal_connect (priv->area, "remove-editable", + G_CALLBACK (remove_editable_cb), scaffold); + + } static void cell_area_scaffold_class_init (CellAreaScaffoldClass *class) { - GObjectClass *gobject_class; - GtkWidgetClass *widget_class; + GObjectClass *gobject_class; + GtkWidgetClass *widget_class; + GtkContainerClass *container_class; - gobject_class = G_OBJECT_CLASS(class); + gobject_class = G_OBJECT_CLASS (class); gobject_class->dispose = cell_area_scaffold_dispose; gobject_class->finalize = cell_area_scaffold_finalize; gobject_class->get_property = cell_area_scaffold_get_property; gobject_class->set_property = cell_area_scaffold_set_property; - widget_class = GTK_WIDGET_CLASS(class); + widget_class = GTK_WIDGET_CLASS (class); widget_class->realize = cell_area_scaffold_realize; widget_class->unrealize = cell_area_scaffold_unrealize; widget_class->draw = cell_area_scaffold_draw; @@ -206,6 +244,10 @@ cell_area_scaffold_class_init (CellAreaScaffoldClass *class) widget_class->focus = cell_area_scaffold_focus; widget_class->button_press_event = cell_area_scaffold_button_press; + container_class = GTK_CONTAINER_CLASS (class); + container_class->forall = cell_area_scaffold_forall; + container_class->remove = cell_area_scaffold_remove; + class->activate = cell_area_scaffold_activate; g_object_class_override_property (gobject_class, PROP_ORIENTATION, "orientation"); @@ -264,6 +306,8 @@ cell_area_scaffold_dispose (GObject *object) { /* Disconnect signals */ g_signal_handler_disconnect (priv->area, priv->focus_changed_id); + g_signal_handler_disconnect (priv->area, priv->editing_started_id); + g_signal_handler_disconnect (priv->area, priv->remove_editable_id); g_object_unref (priv->area); priv->area = NULL; @@ -443,6 +487,9 @@ cell_area_scaffold_draw (GtkWidget *widget, valid = gtk_tree_model_iter_next (priv->model, &iter); } + /* Draw the edit widget after drawing everything else */ + GTK_WIDGET_CLASS (cell_area_scaffold_parent_class)->draw (widget, cr); + return FALSE; } @@ -538,6 +585,10 @@ cell_area_scaffold_size_allocate (GtkWidget *widget, allocation->width, allocation->height); + /* Allocate the child GtkCellEditable widget if one is currently editing a row */ + if (priv->edit_widget) + gtk_widget_size_allocate (priv->edit_widget, &priv->edit_rect); + if (!priv->model) return; @@ -546,13 +597,13 @@ cell_area_scaffold_size_allocate (GtkWidget *widget, /* Cache the per-row sizes and allocate the iter */ if (orientation == GTK_ORIENTATION_HORIZONTAL) { - get_row_sizes (scaffold, priv->row_data, allocation->width); gtk_cell_area_iter_allocate_width (priv->iter, allocation->width); + get_row_sizes (scaffold, priv->row_data, allocation->width); } else { - get_row_sizes (scaffold, priv->row_data, allocation->height); gtk_cell_area_iter_allocate_height (priv->iter, allocation->height); + get_row_sizes (scaffold, priv->row_data, allocation->height); } } @@ -892,8 +943,8 @@ cell_area_scaffold_button_press (GtkWidget *widget, { event_area.height = data->size; - if (event->y >= allocation.y + event_area.y && - event->y <= allocation.y + event_area.y + event_area.height) + if (event->y >= event_area.y && + event->y <= event_area.y + event_area.height) { /* XXX A real implementation would assemble GtkCellRendererState flags here */ gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE); @@ -909,8 +960,8 @@ cell_area_scaffold_button_press (GtkWidget *widget, { event_area.width = data->size; - if (event->x >= allocation.x + event_area.x && - event->x <= allocation.x + event_area.x + event_area.width) + if (event->x >= event_area.x && + event->x <= event_area.x + event_area.width) { /* XXX A real implementation would assemble GtkCellRendererState flags here */ gtk_cell_area_apply_attributes (priv->area, priv->model, &iter, FALSE, FALSE); @@ -930,6 +981,55 @@ cell_area_scaffold_button_press (GtkWidget *widget, return handled; } + +/********************************************************* + * GtkContainerClass * + *********************************************************/ +static void +cell_area_scaffold_put_edit_widget (CellAreaScaffold *scaffold, + GtkWidget *edit_widget, + gint x, + gint y, + gint width, + gint height) +{ + CellAreaScaffoldPrivate *priv = scaffold->priv; + + priv->edit_rect.x = x; + priv->edit_rect.y = y; + priv->edit_rect.width = width; + priv->edit_rect.height = height; + priv->edit_widget = edit_widget; + + gtk_widget_set_parent (edit_widget, GTK_WIDGET (scaffold)); +} + +static void +cell_area_scaffold_forall (GtkContainer *container, + gboolean include_internals, + GtkCallback callback, + gpointer callback_data) +{ + CellAreaScaffold *scaffold = CELL_AREA_SCAFFOLD (container); + CellAreaScaffoldPrivate *priv = scaffold->priv; + + if (priv->edit_widget) + (* callback) (priv->edit_widget, callback_data); +} + +static void +cell_area_scaffold_remove (GtkContainer *container, + GtkWidget *child) +{ + CellAreaScaffold *scaffold = CELL_AREA_SCAFFOLD (container); + CellAreaScaffoldPrivate *priv = scaffold->priv; + + g_return_if_fail (child == priv->edit_widget); + + gtk_widget_unparent (priv->edit_widget); + priv->edit_widget = NULL; +} + /********************************************************* * CellAreaScaffoldClass * *********************************************************/ @@ -1005,7 +1105,6 @@ focus_changed_cb (GtkCellArea *area, CellAreaScaffoldPrivate *priv = scaffold->priv; GtkWidget *widget = GTK_WIDGET (scaffold); GtkTreePath *treepath; - gboolean found = FALSE; gint *indices; if (!priv->model) @@ -1023,8 +1122,6 @@ focus_changed_cb (GtkCellArea *area, gtk_tree_path_free (treepath); - g_print ("Focus changed signal, new focus row %d\n", priv->focus_row); - /* Make sure we have focus now */ if (!gtk_widget_has_focus (widget)) gtk_widget_grab_focus (widget); @@ -1032,6 +1129,36 @@ focus_changed_cb (GtkCellArea *area, gtk_widget_queue_draw (widget); } +static void +editing_started_cb (GtkCellArea *area, + GtkCellRenderer *renderer, + GtkCellEditable *edit_widget, + GdkRectangle *cell_area, + const gchar *path, + CellAreaScaffold *scaffold) +{ + GtkAllocation allocation; + + gtk_widget_get_allocation (GTK_WIDGET (scaffold), &allocation); + + cell_area_scaffold_put_edit_widget (scaffold, GTK_WIDGET (edit_widget), + allocation.x + cell_area->x, + allocation.y + cell_area->y, + cell_area->width, cell_area->height); + + gtk_cell_editable_start_editing (edit_widget, NULL); + gtk_widget_grab_focus (GTK_WIDGET (edit_widget)); +} + +static void +remove_editable_cb (GtkCellArea *area, + GtkCellRenderer *renderer, + GtkCellEditable *edit_widget, + CellAreaScaffold *scaffold) +{ + gtk_container_remove (GTK_CONTAINER (scaffold), GTK_WIDGET (edit_widget)); +} + static void rebuild_and_flush_internals (CellAreaScaffold *scaffold) { diff --git a/tests/cellareascaffold.h b/tests/cellareascaffold.h index 411ecf8cf9..cf9fa06726 100644 --- a/tests/cellareascaffold.h +++ b/tests/cellareascaffold.h @@ -43,14 +43,14 @@ typedef struct _CellAreaScaffoldPrivate CellAreaScaffoldPrivate; struct _CellAreaScaffold { - GtkWidget widget; + GtkContainer widget; CellAreaScaffoldPrivate *priv; }; struct _CellAreaScaffoldClass { - GtkWidgetClass parent_class; + GtkContainerClass parent_class; void (* activate) (CellAreaScaffold *scaffold); }; diff --git a/tests/testcellarea.c b/tests/testcellarea.c index 0acf2ebbb5..c6db6ae5e5 100644 --- a/tests/testcellarea.c +++ b/tests/testcellarea.c @@ -291,7 +291,7 @@ focus_list_model (void) static void cell_toggled (GtkCellRendererToggle *cell_renderer, - gchar *path, + const gchar *path, CellAreaScaffold *scaffold) { GtkTreeModel *model = cell_area_scaffold_get_model (scaffold); @@ -307,6 +307,23 @@ cell_toggled (GtkCellRendererToggle *cell_renderer, gtk_list_store_set (GTK_LIST_STORE (model), &iter, FOCUS_COLUMN_CHECK, !active, -1); } +static void +cell_edited (GtkCellRendererToggle *cell_renderer, + const gchar *path, + const gchar *new_text, + CellAreaScaffold *scaffold) +{ + GtkTreeModel *model = cell_area_scaffold_get_model (scaffold); + GtkTreeIter iter; + + g_print ("Cell edited with new text '%s' !\n", new_text); + + if (!gtk_tree_model_get_iter_from_string (model, &iter, path)) + return; + + gtk_list_store_set (GTK_LIST_STORE (model), &iter, FOCUS_COLUMN_NAME, new_text, -1); +} + static GtkWidget * focus_scaffold (void) { @@ -329,7 +346,9 @@ focus_scaffold (void) gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, TRUE, FALSE); gtk_cell_area_attribute_connect (area, renderer, "text", FOCUS_COLUMN_NAME); - /* Catch signal ... */ + g_signal_connect (G_OBJECT (renderer), "edited", + G_CALLBACK (cell_edited), scaffold); + focus_renderer = renderer = gtk_cell_renderer_toggle_new (); g_object_set (G_OBJECT (renderer), "xalign", 0.0F, NULL); gtk_cell_area_box_pack_start (GTK_CELL_AREA_BOX (area), renderer, FALSE, TRUE);