[gtk+/treeview-refactor] Ironed out the kinks in editing apis for GtkCellArea
- From: Tristan Van Berkom <tvb src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/treeview-refactor] Ironed out the kinks in editing apis for GtkCellArea
- Date: Fri, 12 Nov 2010 10:23:32 +0000 (UTC)
commit 38666b406fe8b2f08e0d67014daea951c6efea73
Author: Tristan Van Berkom <tristan van berkom gmail com>
Date: Fri Nov 12 19:25:07 2010 +0900
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 95eca93..7427254 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;
+
+ 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);
- 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);
+ aligned_area->x += x_offset;
+ aligned_area->y += y_offset;
}
void
diff --git a/gtk/gtkcellarea.h b/gtk/gtkcellarea.h
index 6688451..2ef9178 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 7fbcf9b..a6f6acd 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 9332f3a..248bd6e 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 3e3787a..66750b0 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 411ecf8..cf9fa06 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 0acf2eb..c6db6ae 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);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]