mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2024-12-27 06:00:22 +00:00
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.
This commit is contained in:
parent
7e821aa980
commit
38666b406f
@ -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,6 +2311,9 @@ 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);
|
||||
|
||||
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,6 +89,16 @@ 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,
|
||||
@ -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,13 +198,23 @@ 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
|
||||
@ -185,14 +222,15 @@ cell_area_scaffold_class_init (CellAreaScaffoldClass *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)
|
||||
{
|
||||
|
@ -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);
|
||||
};
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user