mirror of
https://gitlab.gnome.org/GNOME/gtk.git
synced 2025-01-04 09:40:19 +00:00
3c451b3ec7
When a cell is removed from the columnview, we need to make sure it s not just removed from the cell (via unset_parent()) but also from the column. Previously, we were doing this from dispose(), but this is broken because dispose() only runs when the refcount goes to zero. But if some code still has a reference for whatever reason, this won't happen. So now we do it explicitly together with unset_parent().
601 lines
20 KiB
C
601 lines
20 KiB
C
/*
|
|
* Copyright © 2023 Benjamin Otte
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2.1 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public
|
|
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors: Benjamin Otte <otte@gnome.org>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include "gtkcolumnviewrowwidgetprivate.h"
|
|
|
|
#include "gtkbinlayout.h"
|
|
#include "gtkcolumnviewprivate.h"
|
|
#include "gtkcolumnviewcellwidgetprivate.h"
|
|
#include "gtkcolumnviewcolumnprivate.h"
|
|
#include "gtkcolumnviewrowprivate.h"
|
|
#include "gtkcolumnviewtitleprivate.h"
|
|
#include "gtklistitemfactoryprivate.h"
|
|
#include "gtklistbaseprivate.h"
|
|
#include "gtkwidget.h"
|
|
#include "gtkwidgetprivate.h"
|
|
|
|
G_DEFINE_TYPE (GtkColumnViewRowWidget, gtk_column_view_row_widget, GTK_TYPE_LIST_FACTORY_WIDGET)
|
|
|
|
static GtkColumnView *
|
|
gtk_column_view_row_widget_get_column_view (GtkColumnViewRowWidget *self)
|
|
{
|
|
GtkWidget *parent = _gtk_widget_get_parent (GTK_WIDGET (self));
|
|
|
|
if (GTK_IS_COLUMN_VIEW (parent))
|
|
return GTK_COLUMN_VIEW (parent);
|
|
|
|
parent = _gtk_widget_get_parent (parent);
|
|
g_assert (GTK_IS_COLUMN_VIEW (parent));
|
|
|
|
return GTK_COLUMN_VIEW (parent);
|
|
}
|
|
|
|
static gboolean
|
|
gtk_column_view_row_widget_is_header (GtkColumnViewRowWidget *self)
|
|
{
|
|
return gtk_widget_get_css_name (GTK_WIDGET (self)) == g_intern_static_string ("header");
|
|
}
|
|
|
|
static GtkColumnViewColumn *
|
|
gtk_column_view_row_child_get_column (GtkWidget *child)
|
|
{
|
|
if (GTK_IS_COLUMN_VIEW_CELL_WIDGET (child))
|
|
return gtk_column_view_cell_widget_get_column (GTK_COLUMN_VIEW_CELL_WIDGET (child));
|
|
else
|
|
return gtk_column_view_title_get_column (GTK_COLUMN_VIEW_TITLE (child));
|
|
|
|
g_return_val_if_reached (NULL);
|
|
}
|
|
|
|
static GtkWidget *
|
|
gtk_column_view_row_widget_find_child (GtkColumnViewRowWidget *self,
|
|
GtkColumnViewColumn *column)
|
|
{
|
|
GtkWidget *child;
|
|
|
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
|
child;
|
|
child = gtk_widget_get_next_sibling (child))
|
|
{
|
|
if (gtk_column_view_row_child_get_column (child) == column)
|
|
return child;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_update (GtkListItemBase *base,
|
|
guint position,
|
|
gpointer item,
|
|
gboolean selected)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (base);
|
|
GtkWidget *child;
|
|
|
|
if (gtk_column_view_row_widget_is_header (self))
|
|
return;
|
|
|
|
GTK_LIST_ITEM_BASE_CLASS (gtk_column_view_row_widget_parent_class)->update (base, position, item, selected);
|
|
|
|
for (child = gtk_widget_get_first_child (GTK_WIDGET (self));
|
|
child;
|
|
child = gtk_widget_get_next_sibling (child))
|
|
{
|
|
gtk_list_item_base_update (GTK_LIST_ITEM_BASE (child), position, item, selected);
|
|
}
|
|
}
|
|
|
|
static gpointer
|
|
gtk_column_view_row_widget_create_object (GtkListFactoryWidget *fw)
|
|
{
|
|
return gtk_column_view_row_new ();
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_setup_object (GtkListFactoryWidget *fw,
|
|
gpointer object)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (fw);
|
|
GtkColumnViewRow *row = object;
|
|
|
|
g_assert (!gtk_column_view_row_widget_is_header (self));
|
|
|
|
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->setup_object (fw, object);
|
|
|
|
row->owner = self;
|
|
|
|
gtk_list_factory_widget_set_activatable (fw, row->activatable);
|
|
gtk_list_factory_widget_set_selectable (fw, row->selectable);
|
|
gtk_widget_set_focusable (GTK_WIDGET (self), row->focusable);
|
|
|
|
gtk_accessible_update_property (GTK_ACCESSIBLE (self),
|
|
GTK_ACCESSIBLE_PROPERTY_LABEL, row->accessible_label,
|
|
GTK_ACCESSIBLE_PROPERTY_DESCRIPTION, row->accessible_description,
|
|
-1);
|
|
|
|
gtk_column_view_row_do_notify (row,
|
|
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
|
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION,
|
|
gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self)));
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_teardown_object (GtkListFactoryWidget *fw,
|
|
gpointer object)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (fw);
|
|
GtkColumnViewRow *row = object;
|
|
|
|
g_assert (!gtk_column_view_row_widget_is_header (self));
|
|
|
|
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->teardown_object (fw, object);
|
|
|
|
row->owner = NULL;
|
|
|
|
gtk_list_factory_widget_set_activatable (fw, FALSE);
|
|
gtk_list_factory_widget_set_selectable (fw, FALSE);
|
|
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
|
|
|
gtk_accessible_reset_property (GTK_ACCESSIBLE (self), GTK_ACCESSIBLE_PROPERTY_LABEL);
|
|
gtk_accessible_reset_property (GTK_ACCESSIBLE (self), GTK_ACCESSIBLE_PROPERTY_DESCRIPTION);
|
|
|
|
gtk_column_view_row_do_notify (row,
|
|
gtk_list_item_base_get_item (GTK_LIST_ITEM_BASE (self)) != NULL,
|
|
gtk_list_item_base_get_position (GTK_LIST_ITEM_BASE (self)) != GTK_INVALID_LIST_POSITION,
|
|
gtk_list_item_base_get_selected (GTK_LIST_ITEM_BASE (self)));
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_update_object (GtkListFactoryWidget *fw,
|
|
gpointer object,
|
|
guint position,
|
|
gpointer item,
|
|
gboolean selected)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (fw);
|
|
GtkListItemBase *base = GTK_LIST_ITEM_BASE (self);
|
|
GtkColumnViewRow *row = object;
|
|
/* Track notify manually instead of freeze/thaw_notify for performance reasons. */
|
|
gboolean notify_item = FALSE, notify_position = FALSE, notify_selected = FALSE;
|
|
|
|
g_assert (!gtk_column_view_row_widget_is_header (self));
|
|
|
|
/* FIXME: It's kinda evil to notify external objects from here... */
|
|
notify_item = gtk_list_item_base_get_item (base) != item;
|
|
notify_position = gtk_list_item_base_get_position (base) != position;
|
|
notify_selected = gtk_list_item_base_get_selected (base) != selected;
|
|
|
|
GTK_LIST_FACTORY_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->update_object (fw,
|
|
object,
|
|
position,
|
|
item,
|
|
selected);
|
|
|
|
if (row)
|
|
gtk_column_view_row_do_notify (row, notify_item, notify_position, notify_selected);
|
|
}
|
|
|
|
static GtkWidget *
|
|
gtk_column_view_next_focus_widget (GtkWidget *widget,
|
|
GtkWidget *current,
|
|
GtkDirectionType direction)
|
|
{
|
|
gboolean forward;
|
|
|
|
switch (direction)
|
|
{
|
|
case GTK_DIR_TAB_FORWARD:
|
|
forward = TRUE;
|
|
break;
|
|
case GTK_DIR_TAB_BACKWARD:
|
|
forward = FALSE;
|
|
break;
|
|
case GTK_DIR_LEFT:
|
|
forward = gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL;
|
|
break;
|
|
case GTK_DIR_RIGHT:
|
|
forward = gtk_widget_get_direction (widget) != GTK_TEXT_DIR_RTL;
|
|
break;
|
|
case GTK_DIR_UP:
|
|
case GTK_DIR_DOWN:
|
|
return NULL;
|
|
default:
|
|
g_return_val_if_reached (NULL);
|
|
}
|
|
|
|
if (forward)
|
|
{
|
|
if (current == NULL)
|
|
return widget;
|
|
else if (current == widget)
|
|
return gtk_widget_get_first_child (widget);
|
|
else
|
|
return gtk_widget_get_next_sibling (current);
|
|
}
|
|
else
|
|
{
|
|
if (current == NULL)
|
|
return gtk_widget_get_last_child (widget);
|
|
else if (current == widget)
|
|
return NULL;
|
|
else
|
|
{
|
|
current = gtk_widget_get_prev_sibling (current);
|
|
if (current)
|
|
return current;
|
|
else
|
|
return widget;
|
|
}
|
|
}
|
|
}
|
|
|
|
static gboolean
|
|
gtk_column_view_row_widget_focus (GtkWidget *widget,
|
|
GtkDirectionType direction)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (widget);
|
|
GtkWidget *child, *current;
|
|
GtkColumnView *view;
|
|
|
|
current = gtk_widget_get_focus_child (widget);
|
|
|
|
view = gtk_column_view_row_widget_get_column_view (self);
|
|
if (gtk_column_view_get_tab_behavior (view) == GTK_LIST_TAB_CELL &&
|
|
(direction == GTK_DIR_TAB_FORWARD || direction == GTK_DIR_TAB_BACKWARD))
|
|
{
|
|
if (current || gtk_widget_is_focus (widget))
|
|
return FALSE;
|
|
}
|
|
|
|
if (current == NULL)
|
|
{
|
|
GtkColumnViewColumn *focus_column = gtk_column_view_get_focus_column (view);
|
|
if (focus_column)
|
|
{
|
|
current = gtk_column_view_row_widget_find_child (self, focus_column);
|
|
if (current && gtk_widget_child_focus (current, direction))
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
if (gtk_widget_is_focus (widget))
|
|
current = widget;
|
|
|
|
for (child = gtk_column_view_next_focus_widget (widget, current, direction);
|
|
child;
|
|
child = gtk_column_view_next_focus_widget (widget, child, direction))
|
|
{
|
|
if (child == widget)
|
|
{
|
|
if (gtk_widget_grab_focus_self (widget))
|
|
{
|
|
gtk_column_view_set_focus_column (view, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
}
|
|
else if (child)
|
|
{
|
|
if (gtk_widget_child_focus (child, direction))
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static gboolean
|
|
gtk_column_view_row_widget_grab_focus (GtkWidget *widget)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (widget);
|
|
GtkWidget *child, *focus_child;
|
|
GtkColumnViewColumn *focus_column;
|
|
GtkColumnView *view;
|
|
|
|
view = gtk_column_view_row_widget_get_column_view (self);
|
|
focus_column = gtk_column_view_get_focus_column (view);
|
|
if (focus_column)
|
|
{
|
|
focus_child = gtk_column_view_row_widget_find_child (self, focus_column);
|
|
if (focus_child && gtk_widget_grab_focus (focus_child))
|
|
return TRUE;
|
|
}
|
|
else
|
|
focus_child = NULL;
|
|
|
|
if (gtk_widget_grab_focus_self (widget))
|
|
{
|
|
gtk_column_view_set_focus_column (view, NULL, FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
for (child = focus_child ? gtk_widget_get_next_sibling (focus_child) : gtk_widget_get_first_child (widget);
|
|
child != focus_child;
|
|
child = child ? gtk_widget_get_next_sibling (child) : gtk_widget_get_first_child (widget))
|
|
{
|
|
/* When we started iterating at focus_child, we want to iterate over the rest
|
|
* of the children, too */
|
|
if (child == NULL)
|
|
continue;
|
|
|
|
if (gtk_widget_grab_focus (child))
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_set_focus_child (GtkWidget *widget,
|
|
GtkWidget *child)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (widget);
|
|
|
|
GTK_WIDGET_CLASS (gtk_column_view_row_widget_parent_class)->set_focus_child (widget, child);
|
|
|
|
if (child)
|
|
{
|
|
gtk_column_view_set_focus_column (gtk_column_view_row_widget_get_column_view (self),
|
|
gtk_column_view_row_child_get_column (child),
|
|
TRUE);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_dispose (GObject *object)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (object);
|
|
GtkWidget *child;
|
|
|
|
while ((child = gtk_widget_get_first_child (GTK_WIDGET (self))))
|
|
{
|
|
gtk_column_view_row_widget_remove_child (self, child);
|
|
}
|
|
|
|
G_OBJECT_CLASS (gtk_column_view_row_widget_parent_class)->dispose (object);
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_measure_along (GtkColumnViewRowWidget *self,
|
|
int for_size,
|
|
int *minimum,
|
|
int *natural,
|
|
int *minimum_baseline,
|
|
int *natural_baseline)
|
|
{
|
|
GtkOrientation orientation = GTK_ORIENTATION_VERTICAL;
|
|
GtkColumnView *view;
|
|
GtkWidget *child;
|
|
guint i, n;
|
|
GtkRequestedSize *sizes = NULL;
|
|
|
|
view = gtk_column_view_row_widget_get_column_view (self);
|
|
|
|
if (for_size > -1)
|
|
{
|
|
n = g_list_model_get_n_items (gtk_column_view_get_columns (view));
|
|
sizes = g_newa (GtkRequestedSize, n);
|
|
gtk_column_view_distribute_width (view, for_size, sizes);
|
|
}
|
|
|
|
for (child = _gtk_widget_get_first_child (GTK_WIDGET (self)), i = 0;
|
|
child != NULL;
|
|
child = _gtk_widget_get_next_sibling (child), i++)
|
|
{
|
|
int child_min = 0;
|
|
int child_nat = 0;
|
|
int child_min_baseline = -1;
|
|
int child_nat_baseline = -1;
|
|
|
|
if (!gtk_widget_should_layout (child))
|
|
continue;
|
|
|
|
gtk_widget_measure (child, orientation,
|
|
for_size > -1 ? sizes[i].minimum_size : -1,
|
|
&child_min, &child_nat,
|
|
&child_min_baseline, &child_nat_baseline);
|
|
|
|
*minimum = MAX (*minimum, child_min);
|
|
*natural = MAX (*natural, child_nat);
|
|
|
|
if (child_min_baseline > -1)
|
|
*minimum_baseline = MAX (*minimum_baseline, child_min_baseline);
|
|
if (child_nat_baseline > -1)
|
|
*natural_baseline = MAX (*natural_baseline, child_nat_baseline);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_measure (GtkWidget *widget,
|
|
GtkOrientation orientation,
|
|
int for_size,
|
|
int *minimum,
|
|
int *natural,
|
|
int *minimum_baseline,
|
|
int *natural_baseline)
|
|
{
|
|
GtkColumnViewRowWidget *self = GTK_COLUMN_VIEW_ROW_WIDGET (widget);
|
|
|
|
if (orientation == GTK_ORIENTATION_HORIZONTAL)
|
|
{
|
|
gtk_column_view_measure_across (gtk_column_view_row_widget_get_column_view (self),
|
|
minimum,
|
|
natural);
|
|
}
|
|
else
|
|
{
|
|
gtk_column_view_row_widget_measure_along (self,
|
|
for_size,
|
|
minimum,
|
|
natural,
|
|
minimum_baseline,
|
|
natural_baseline);
|
|
}
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_allocate (GtkWidget *widget,
|
|
int width,
|
|
int height,
|
|
int baseline)
|
|
{
|
|
GtkWidget *child;
|
|
|
|
for (child = _gtk_widget_get_first_child (widget);
|
|
child != NULL;
|
|
child = _gtk_widget_get_next_sibling (child))
|
|
{
|
|
GtkColumnViewColumn *column;
|
|
int col_x, col_width, min;
|
|
|
|
if (!gtk_widget_should_layout (child))
|
|
continue;
|
|
|
|
column = gtk_column_view_row_child_get_column (child);
|
|
gtk_column_view_column_get_header_allocation (column, &col_x, &col_width);
|
|
|
|
gtk_widget_measure (child, GTK_ORIENTATION_HORIZONTAL, -1, &min, NULL, NULL, NULL);
|
|
|
|
gtk_widget_size_allocate (child, &(GtkAllocation) { col_x, 0, MAX (min, col_width), height }, baseline);
|
|
}
|
|
}
|
|
|
|
static void
|
|
add_arrow_bindings (GtkWidgetClass *widget_class,
|
|
guint keysym,
|
|
GtkDirectionType direction)
|
|
{
|
|
guint keypad_keysym = keysym - GDK_KEY_Left + GDK_KEY_KP_Left;
|
|
|
|
gtk_widget_class_add_binding_signal (widget_class, keysym, 0,
|
|
"move-focus",
|
|
"(i)",
|
|
direction);
|
|
gtk_widget_class_add_binding_signal (widget_class, keysym, GDK_CONTROL_MASK,
|
|
"move-focus",
|
|
"(i)",
|
|
direction);
|
|
gtk_widget_class_add_binding_signal (widget_class, keypad_keysym, 0,
|
|
"move-focus",
|
|
"(i)",
|
|
direction);
|
|
gtk_widget_class_add_binding_signal (widget_class, keypad_keysym, GDK_CONTROL_MASK,
|
|
"move-focus",
|
|
"(i)",
|
|
direction);
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_class_init (GtkColumnViewRowWidgetClass *klass)
|
|
{
|
|
GtkListFactoryWidgetClass *factory_class = GTK_LIST_FACTORY_WIDGET_CLASS (klass);
|
|
GtkListItemBaseClass *base_class = GTK_LIST_ITEM_BASE_CLASS (klass);
|
|
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
factory_class->create_object = gtk_column_view_row_widget_create_object;
|
|
factory_class->setup_object = gtk_column_view_row_widget_setup_object;
|
|
factory_class->update_object = gtk_column_view_row_widget_update_object;
|
|
factory_class->teardown_object = gtk_column_view_row_widget_teardown_object;
|
|
|
|
base_class->update = gtk_column_view_row_widget_update;
|
|
|
|
widget_class->focus = gtk_column_view_row_widget_focus;
|
|
widget_class->grab_focus = gtk_column_view_row_widget_grab_focus;
|
|
widget_class->set_focus_child = gtk_column_view_row_widget_set_focus_child;
|
|
widget_class->measure = gtk_column_view_row_widget_measure;
|
|
widget_class->size_allocate = gtk_column_view_row_widget_allocate;
|
|
|
|
object_class->dispose = gtk_column_view_row_widget_dispose;
|
|
|
|
add_arrow_bindings (widget_class, GDK_KEY_Left, GTK_DIR_LEFT);
|
|
add_arrow_bindings (widget_class, GDK_KEY_Right, GTK_DIR_RIGHT);
|
|
|
|
/* This gets overwritten by gtk_column_view_row_widget_new() but better safe than sorry */
|
|
gtk_widget_class_set_css_name (widget_class, g_intern_static_string ("row"));
|
|
gtk_widget_class_set_accessible_role (widget_class, GTK_ACCESSIBLE_ROLE_ROW);
|
|
}
|
|
|
|
static void
|
|
gtk_column_view_row_widget_init (GtkColumnViewRowWidget *self)
|
|
{
|
|
gtk_widget_set_focusable (GTK_WIDGET (self), TRUE);
|
|
}
|
|
|
|
GtkWidget *
|
|
gtk_column_view_row_widget_new (GtkListItemFactory *factory,
|
|
gboolean is_header)
|
|
{
|
|
return g_object_new (GTK_TYPE_COLUMN_VIEW_ROW_WIDGET,
|
|
"factory", factory,
|
|
"css-name", is_header ? "header" : "row",
|
|
"selectable", TRUE,
|
|
"activatable", TRUE,
|
|
NULL);
|
|
}
|
|
|
|
void
|
|
gtk_column_view_row_widget_add_child (GtkColumnViewRowWidget *self,
|
|
GtkWidget *child)
|
|
{
|
|
gtk_widget_set_parent (child, GTK_WIDGET (self));
|
|
}
|
|
|
|
void
|
|
gtk_column_view_row_widget_reorder_child (GtkColumnViewRowWidget *self,
|
|
GtkWidget *child,
|
|
guint position)
|
|
{
|
|
GtkWidget *widget = GTK_WIDGET (self);
|
|
GtkWidget *sibling = NULL;
|
|
|
|
if (position > 0)
|
|
{
|
|
GtkWidget *c;
|
|
guint i;
|
|
|
|
for (c = gtk_widget_get_first_child (widget), i = 0;
|
|
c;
|
|
c = gtk_widget_get_next_sibling (c), i++)
|
|
{
|
|
if (i + 1 == position)
|
|
{
|
|
sibling = c;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (child != sibling)
|
|
gtk_widget_insert_after (child, widget, sibling);
|
|
}
|
|
|
|
void
|
|
gtk_column_view_row_widget_remove_child (GtkColumnViewRowWidget *self,
|
|
GtkWidget *child)
|
|
{
|
|
if (GTK_IS_COLUMN_VIEW_CELL_WIDGET (child))
|
|
gtk_column_view_cell_widget_unset_column (GTK_COLUMN_VIEW_CELL_WIDGET (child));
|
|
|
|
gtk_widget_unparent (child);
|
|
}
|
|
|