/* * Copyright © 2019 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 . * * Authors: Benjamin Otte */ #include "config.h" #include "gtkcolumnviewcolumnprivate.h" #include "gtkcolumnviewsorterprivate.h" #include "gtkcolumnviewprivate.h" #include "gtkcolumnviewrowwidgetprivate.h" #include "gtkcolumnviewtitleprivate.h" #include "gtklistbaseprivate.h" #include "gtkmain.h" #include "gtkprivate.h" #include "gtkrbtreeprivate.h" #include "gtksizegroup.h" #include "gtkwidgetprivate.h" #include "gtksorter.h" /** * GtkColumnViewColumn: * * `GtkColumnViewColumn` represents the columns being added to a `GtkColumnView`. * * The main ingredient for a `GtkColumnViewColumn` is the `GtkListItemFactory` * that tells the columnview how to create cells for this column from items in * the model. * * Columns have a title, and can optionally have a header menu set * with [method@Gtk.ColumnViewColumn.set_header_menu]. * * A sorter can be associated with a column using * [method@Gtk.ColumnViewColumn.set_sorter], to let users influence sorting * by clicking on the column header. */ struct _GtkColumnViewColumn { GObject parent_instance; GtkListItemFactory *factory; char *title; char *id; GtkSorter *sorter; /* data for the view */ GtkColumnView *view; GtkWidget *header; int minimum_size_request; int natural_size_request; int allocation_offset; int allocation_size; int header_position; int fixed_width; guint visible : 1; guint resizable : 1; guint expand : 1; GMenuModel *menu; /* This list isn't sorted - this is just caching for performance */ GtkColumnViewCellWidget *first_cell; /* no reference, just caching */ }; struct _GtkColumnViewColumnClass { GObjectClass parent_class; }; enum { PROP_0, PROP_COLUMN_VIEW, PROP_FACTORY, PROP_TITLE, PROP_SORTER, PROP_VISIBLE, PROP_HEADER_MENU, PROP_RESIZABLE, PROP_EXPAND, PROP_FIXED_WIDTH, PROP_ID, N_PROPS }; G_DEFINE_TYPE (GtkColumnViewColumn, gtk_column_view_column, G_TYPE_OBJECT) static GParamSpec *properties[N_PROPS] = { NULL, }; static void gtk_column_view_column_dispose (GObject *object) { GtkColumnViewColumn *self = GTK_COLUMN_VIEW_COLUMN (object); g_assert (self->view == NULL); /* would hold a ref otherwise */ g_assert (self->first_cell == NULL); /* no view = no children */ g_clear_object (&self->factory); g_clear_object (&self->sorter); g_clear_pointer (&self->title, g_free); g_clear_object (&self->menu); g_clear_pointer (&self->id, g_free); G_OBJECT_CLASS (gtk_column_view_column_parent_class)->dispose (object); } static void gtk_column_view_column_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) { GtkColumnViewColumn *self = GTK_COLUMN_VIEW_COLUMN (object); switch (property_id) { case PROP_COLUMN_VIEW: g_value_set_object (value, self->view); break; case PROP_FACTORY: g_value_set_object (value, self->factory); break; case PROP_TITLE: g_value_set_string (value, self->title); break; case PROP_SORTER: g_value_set_object (value, self->sorter); break; case PROP_VISIBLE: g_value_set_boolean (value, self->visible); break; case PROP_HEADER_MENU: g_value_set_object (value, self->menu); break; case PROP_RESIZABLE: g_value_set_boolean (value, self->resizable); break; case PROP_EXPAND: g_value_set_boolean (value, self->expand); break; case PROP_FIXED_WIDTH: g_value_set_int (value, self->fixed_width); break; case PROP_ID: g_value_set_string (value, self->id); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gtk_column_view_column_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) { GtkColumnViewColumn *self = GTK_COLUMN_VIEW_COLUMN (object); switch (property_id) { case PROP_FACTORY: gtk_column_view_column_set_factory (self, g_value_get_object (value)); break; case PROP_TITLE: gtk_column_view_column_set_title (self, g_value_get_string (value)); break; case PROP_SORTER: gtk_column_view_column_set_sorter (self, g_value_get_object (value)); break; case PROP_VISIBLE: gtk_column_view_column_set_visible (self, g_value_get_boolean (value)); break; case PROP_HEADER_MENU: gtk_column_view_column_set_header_menu (self, g_value_get_object (value)); break; case PROP_RESIZABLE: gtk_column_view_column_set_resizable (self, g_value_get_boolean (value)); break; case PROP_EXPAND: gtk_column_view_column_set_expand (self, g_value_get_boolean (value)); break; case PROP_FIXED_WIDTH: gtk_column_view_column_set_fixed_width (self, g_value_get_int (value)); break; case PROP_ID: gtk_column_view_column_set_id (self, g_value_get_string (value)); break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); break; } } static void gtk_column_view_column_class_init (GtkColumnViewColumnClass *klass) { GObjectClass *gobject_class = G_OBJECT_CLASS (klass); gobject_class->dispose = gtk_column_view_column_dispose; gobject_class->get_property = gtk_column_view_column_get_property; gobject_class->set_property = gtk_column_view_column_set_property; /** * GtkColumnViewColumn:column-view: (attributes org.gtk.Property.get=gtk_column_view_column_get_column_view) * * The `GtkColumnView` this column is a part of. */ properties[PROP_COLUMN_VIEW] = g_param_spec_object ("column-view", NULL, NULL, GTK_TYPE_COLUMN_VIEW, G_PARAM_READABLE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:factory: (attributes org.gtk.Property.get=gtk_column_view_column_get_factory org.gtk.Property.set=gtk_column_view_column_set_factory) * * Factory for populating list items. */ properties[PROP_FACTORY] = g_param_spec_object ("factory", NULL, NULL, GTK_TYPE_LIST_ITEM_FACTORY, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:title: (attributes org.gtk.Property.get=gtk_column_view_column_get_title org.gtk.Property.set=gtk_column_view_column_set_title) * * Title displayed in the header. */ properties[PROP_TITLE] = g_param_spec_string ("title", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); /** * GtkColumnViewColumn:sorter: (attributes org.gtk.Property.get=gtk_column_view_column_get_sorter org.gtk.Property.set=gtk_column_view_column_set_sorter) * * Sorter for sorting items according to this column. */ properties[PROP_SORTER] = g_param_spec_object ("sorter", NULL, NULL, GTK_TYPE_SORTER, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:visible: (attributes org.gtk.Property.get=gtk_column_view_column_get_visible org.gtk.Property.set=gtk_column_view_column_set_visible) * * Whether this column is visible. */ properties[PROP_VISIBLE] = g_param_spec_boolean ("visible", NULL, NULL, TRUE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:header-menu: (attributes org.gtk.Property.get=gtk_column_view_column_get_header_menu org.gtk.Property.set=gtk_column_view_column_set_header_menu) * * Menu model used to create the context menu for the column header. */ properties[PROP_HEADER_MENU] = g_param_spec_object ("header-menu", NULL, NULL, G_TYPE_MENU_MODEL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:resizable: (attributes org.gtk.Property.get=gtk_column_view_column_get_resizable org.gtk.Property.set=gtk_column_view_column_set_resizable) * * Whether this column is resizable. */ properties[PROP_RESIZABLE] = g_param_spec_boolean ("resizable", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:expand: (attributes org.gtk.Property.get=gtk_column_view_column_get_expand org.gtk.Property.set=gtk_column_view_column_set_expand) * * Column gets share of extra width allocated to the view. */ properties[PROP_EXPAND] = g_param_spec_boolean ("expand", NULL, NULL, FALSE, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:fixed-width: (attributes org.gtk.Property.get=gtk_column_view_column_get_fixed_width org.gtk.Property.set=gtk_column_view_column_set_fixed_width) * * If not -1, this is the width that the column is allocated, * regardless of the size of its content. */ properties[PROP_FIXED_WIDTH] = g_param_spec_int ("fixed-width", NULL, NULL, -1, G_MAXINT, -1, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); /** * GtkColumnViewColumn:id: (attributes org.gtk.Property.get=gtk_column_view_column_get_id org.gtk.Property.set=gtk_column_view_column_set_id) * * An ID for the column. * * GTK is not currently using the ID for anything, but * it can be used by applications when saving column view * configurations. * * It is up to applications to ensure uniqueness of IDs. * * Since: 4.10 */ properties[PROP_ID] = g_param_spec_string ("id", NULL, NULL, NULL, G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY); g_object_class_install_properties (gobject_class, N_PROPS, properties); } static void gtk_column_view_column_init (GtkColumnViewColumn *self) { self->minimum_size_request = -1; self->natural_size_request = -1; self->visible = TRUE; self->resizable = FALSE; self->expand = FALSE; self->fixed_width = -1; } /** * gtk_column_view_column_new: * @title: (nullable): Title to use for this column * @factory: (transfer full) (nullable): The factory to populate items with * * Creates a new `GtkColumnViewColumn` that uses the given @factory for * mapping items to widgets. * * You most likely want to call [method@Gtk.ColumnView.append_column] next. * * The function takes ownership of the argument, so you can write code like: * * ```c * column = gtk_column_view_column_new (_("Name"), * gtk_builder_list_item_factory_new_from_resource ("/name.ui")); * ``` * * Returns: a new `GtkColumnViewColumn` using the given @factory */ GtkColumnViewColumn * gtk_column_view_column_new (const char *title, GtkListItemFactory *factory) { GtkColumnViewColumn *result; g_return_val_if_fail (factory == NULL || GTK_IS_LIST_ITEM_FACTORY (factory), NULL); result = g_object_new (GTK_TYPE_COLUMN_VIEW_COLUMN, "factory", factory, "title", title, NULL); g_clear_object (&factory); return result; } GtkColumnViewCellWidget * gtk_column_view_column_get_first_cell (GtkColumnViewColumn *self) { return self->first_cell; } void gtk_column_view_column_add_cell (GtkColumnViewColumn *self, GtkColumnViewCellWidget *cell) { self->first_cell = cell; gtk_widget_set_visible (GTK_WIDGET (cell), self->visible); gtk_column_view_column_queue_resize (self); } void gtk_column_view_column_remove_cell (GtkColumnViewColumn *self, GtkColumnViewCellWidget *cell) { if (cell == self->first_cell) self->first_cell = gtk_column_view_cell_widget_get_next (cell); gtk_column_view_column_queue_resize (self); gtk_widget_queue_resize (GTK_WIDGET (cell)); } void gtk_column_view_column_queue_resize (GtkColumnViewColumn *self) { GtkColumnViewCellWidget *cell; if (self->minimum_size_request < 0) return; self->minimum_size_request = -1; self->natural_size_request = -1; if (self->header) gtk_widget_queue_resize (self->header); for (cell = self->first_cell; cell; cell = gtk_column_view_cell_widget_get_next (cell)) { gtk_widget_queue_resize (GTK_WIDGET (cell)); } } void gtk_column_view_column_measure (GtkColumnViewColumn *self, int *minimum, int *natural) { if (self->fixed_width > -1) { self->minimum_size_request = self->fixed_width; self->natural_size_request = self->fixed_width; } if (self->minimum_size_request < 0) { GtkColumnViewCellWidget *cell; int min, nat, cell_min, cell_nat; if (self->header) { gtk_widget_measure (self->header, GTK_ORIENTATION_HORIZONTAL, -1, &min, &nat, NULL, NULL); } else { min = 0; nat = 0; } for (cell = self->first_cell; cell; cell = gtk_column_view_cell_widget_get_next (cell)) { gtk_widget_measure (GTK_WIDGET (cell), GTK_ORIENTATION_HORIZONTAL, -1, &cell_min, &cell_nat, NULL, NULL); min = MAX (min, cell_min); nat = MAX (nat, cell_nat); } self->minimum_size_request = min; self->natural_size_request = nat; } *minimum = self->minimum_size_request; *natural = self->natural_size_request; } void gtk_column_view_column_allocate (GtkColumnViewColumn *self, int offset, int size) { self->allocation_offset = offset; self->allocation_size = size; self->header_position = offset; } void gtk_column_view_column_get_allocation (GtkColumnViewColumn *self, int *offset, int *size) { if (offset) *offset = self->allocation_offset; if (size) *size = self->allocation_size; } static void gtk_column_view_column_create_cells (GtkColumnViewColumn *self) { GtkListView *list; GtkWidget *row; if (self->first_cell) return; list = gtk_column_view_get_list_view (GTK_COLUMN_VIEW (self->view)); for (row = gtk_widget_get_first_child (GTK_WIDGET (list)); row != NULL; row = gtk_widget_get_next_sibling (row)) { GtkColumnViewRowWidget *list_item; GtkListItemBase *base; GtkWidget *cell; list_item = GTK_COLUMN_VIEW_ROW_WIDGET (row); base = GTK_LIST_ITEM_BASE (row); cell = gtk_column_view_cell_widget_new (self, gtk_column_view_is_inert (self->view)); gtk_column_view_row_widget_add_child (list_item, cell); gtk_list_item_base_update (GTK_LIST_ITEM_BASE (cell), gtk_list_item_base_get_position (base), gtk_list_item_base_get_item (base), gtk_list_item_base_get_selected (base)); } } static void gtk_column_view_column_remove_cells (GtkColumnViewColumn *self) { while (self->first_cell) gtk_column_view_cell_widget_remove (self->first_cell); } static void gtk_column_view_column_create_header (GtkColumnViewColumn *self) { if (self->header != NULL) return; self->header = gtk_column_view_title_new (self); gtk_widget_set_visible (self->header, self->visible); gtk_column_view_row_widget_add_child (gtk_column_view_get_header_widget (self->view), self->header); gtk_column_view_column_queue_resize (self); } static void gtk_column_view_column_remove_header (GtkColumnViewColumn *self) { if (self->header == NULL) return; gtk_column_view_row_widget_remove_child (gtk_column_view_get_header_widget (self->view), self->header); self->header = NULL; gtk_column_view_column_queue_resize (self); } static void gtk_column_view_column_ensure_cells (GtkColumnViewColumn *self) { if (self->view && gtk_column_view_column_get_visible (self)) gtk_column_view_column_create_cells (self); else gtk_column_view_column_remove_cells (self); if (self->view) gtk_column_view_column_create_header (self); else gtk_column_view_column_remove_header (self); } /** * gtk_column_view_column_get_column_view: (attributes org.gtk.Method.get_property=column-view) * @self: a `GtkColumnViewColumn` * * Gets the column view that's currently displaying this column. * * If @self has not been added to a column view yet, %NULL is returned. * * Returns: (nullable) (transfer none): The column view displaying @self. */ GtkColumnView * gtk_column_view_column_get_column_view (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL); return self->view; } void gtk_column_view_column_set_column_view (GtkColumnViewColumn *self, GtkColumnView *view) { if (self->view == view) return; gtk_column_view_column_remove_cells (self); gtk_column_view_column_remove_header (self); self->view = view; gtk_column_view_column_ensure_cells (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_COLUMN_VIEW]); } void gtk_column_view_column_set_position (GtkColumnViewColumn *self, guint position) { GtkColumnViewCellWidget *cell; gtk_column_view_row_widget_reorder_child (gtk_column_view_get_header_widget (self->view), self->header, position); for (cell = self->first_cell; cell; cell = gtk_column_view_cell_widget_get_next (cell)) { GtkColumnViewRowWidget *list_item; list_item = GTK_COLUMN_VIEW_ROW_WIDGET (gtk_widget_get_parent (GTK_WIDGET (cell))); gtk_column_view_row_widget_reorder_child (list_item, GTK_WIDGET (cell), position); } } /** * gtk_column_view_column_get_factory: (attributes org.gtk.Method.get_property=factory) * @self: a `GtkColumnViewColumn` * * Gets the factory that's currently used to populate list items for * this column. * * Returns: (nullable) (transfer none): The factory in use **/ GtkListItemFactory * gtk_column_view_column_get_factory (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL); return self->factory; } void gtk_column_view_column_update_factory (GtkColumnViewColumn *self, gboolean inert) { GtkListItemFactory *factory; GtkColumnViewCellWidget *cell; if (self->factory == NULL) return; if (inert) factory = NULL; else factory = self->factory; for (cell = self->first_cell; cell; cell = gtk_column_view_cell_widget_get_next (cell)) { gtk_list_factory_widget_set_factory (GTK_LIST_FACTORY_WIDGET (cell), factory); } } /** * gtk_column_view_column_set_factory: (attributes org.gtk.Method.set_property=factory) * @self: a `GtkColumnViewColumn` * @factory: (nullable) (transfer none): the factory to use * * Sets the `GtkListItemFactory` to use for populating list items for this * column. */ void gtk_column_view_column_set_factory (GtkColumnViewColumn *self, GtkListItemFactory *factory) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); g_return_if_fail (factory == NULL || GTK_LIST_ITEM_FACTORY (factory)); if (self->factory && !factory) gtk_column_view_column_update_factory (self, TRUE); if (!g_set_object (&self->factory, factory)) return; if (self->view && !gtk_column_view_is_inert (self->view)) gtk_column_view_column_update_factory (self, FALSE); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FACTORY]); } /** * gtk_column_view_column_set_title: (attributes org.gtk.Method.set_property=title) * @self: a `GtkColumnViewColumn` * @title: (nullable): Title to use for this column * * Sets the title of this column. * * The title is displayed in the header of a `GtkColumnView` * for this column and is therefore user-facing text that should * be translated. */ void gtk_column_view_column_set_title (GtkColumnViewColumn *self, const char *title) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); if (g_strcmp0 (self->title, title) == 0) return; g_free (self->title); self->title = g_strdup (title); if (self->header) gtk_column_view_title_set_title (GTK_COLUMN_VIEW_TITLE (self->header), title); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_TITLE]); } /** * gtk_column_view_column_get_title: (attributes org.gtk.Method.get_property=title) * @self: a `GtkColumnViewColumn` * * Returns the title set with gtk_column_view_column_set_title(). * * Returns: (nullable): The column's title */ const char * gtk_column_view_column_get_title (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), FALSE); return self->title; } static void gtk_column_view_column_remove_from_sorter (GtkColumnViewColumn *self) { if (self->view == NULL) return; gtk_column_view_sorter_remove_column (GTK_COLUMN_VIEW_SORTER (gtk_column_view_get_sorter (self->view)), self); } /** * gtk_column_view_column_set_sorter: (attributes org.gtk.Method.set_property=sorter) * @self: a `GtkColumnViewColumn` * @sorter: (nullable): the `GtkSorter` to associate with @column * * Associates a sorter with the column. * * If @sorter is %NULL, the column will not let users change * the sorting by clicking on its header. * * This sorter can be made active by clicking on the column * header, or by calling [method@Gtk.ColumnView.sort_by_column]. * * See [method@Gtk.ColumnView.get_sorter] for the necessary steps * for setting up customizable sorting for [class@Gtk.ColumnView]. */ void gtk_column_view_column_set_sorter (GtkColumnViewColumn *self, GtkSorter *sorter) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); g_return_if_fail (sorter == NULL || GTK_IS_SORTER (sorter)); if (!g_set_object (&self->sorter, sorter)) return; gtk_column_view_column_remove_from_sorter (self); if (self->header) gtk_column_view_title_update_sort (GTK_COLUMN_VIEW_TITLE (self->header)); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SORTER]); } /** * gtk_column_view_column_get_sorter: (attributes org.gtk.Method.get_property=sorter) * @self: a `GtkColumnViewColumn` * * Returns the sorter that is associated with the column. * * Returns: (nullable) (transfer none): the `GtkSorter` of @self */ GtkSorter * gtk_column_view_column_get_sorter (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL); return self->sorter; } void gtk_column_view_column_notify_sort (GtkColumnViewColumn *self) { if (self->header) gtk_column_view_title_update_sort (GTK_COLUMN_VIEW_TITLE (self->header)); } /** * gtk_column_view_column_set_visible: (attributes org.gtk.Method.set_property=visible) * @self: a `GtkColumnViewColumn` * @visible: whether this column should be visible * * Sets whether this column should be visible in views. */ void gtk_column_view_column_set_visible (GtkColumnViewColumn *self, gboolean visible) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); if (self->visible == visible) return; self->visible = visible; self->minimum_size_request = -1; self->natural_size_request = -1; if (self->header) gtk_widget_set_visible (GTK_WIDGET (self->header), visible); gtk_column_view_column_ensure_cells (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VISIBLE]); } /** * gtk_column_view_column_get_visible: (attributes org.gtk.Method.get_property=visible) * @self: a `GtkColumnViewColumn` * * Returns whether this column is visible. * * Returns: %TRUE if this column is visible */ gboolean gtk_column_view_column_get_visible (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), TRUE); return self->visible; } /** * gtk_column_view_column_set_header_menu: (attributes org.gtk.Method.set_property=header-menu) * @self: a `GtkColumnViewColumn` * @menu: (nullable): a `GMenuModel` * * Sets the menu model that is used to create the context menu * for the column header. */ void gtk_column_view_column_set_header_menu (GtkColumnViewColumn *self, GMenuModel *menu) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); g_return_if_fail (menu == NULL || G_IS_MENU_MODEL (menu)); if (!g_set_object (&self->menu, menu)) return; if (self->header) gtk_column_view_title_set_menu (GTK_COLUMN_VIEW_TITLE (self->header), menu); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_HEADER_MENU]); } /** * gtk_column_view_column_get_header_menu: (attributes org.gtk.Method.get_property=header-menu) * @self: a `GtkColumnViewColumn` * * Gets the menu model that is used to create the context menu * for the column header. * * Returns: (transfer none) (nullable): the `GMenuModel` */ GMenuModel * gtk_column_view_column_get_header_menu (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL); return self->menu; } /** * gtk_column_view_column_set_expand: (attributes org.gtk.Method.set_property=expand) * @self: a `GtkColumnViewColumn` * @expand: %TRUE if this column should expand to fill available sace * * Sets the column to take available extra space. * * The extra space is shared equally amongst all columns that * have the expand set to %TRUE. */ void gtk_column_view_column_set_expand (GtkColumnViewColumn *self, gboolean expand) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); if (self->expand == expand) return; self->expand = expand; if (self->visible && self->view) gtk_widget_queue_resize (GTK_WIDGET (self->view)); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_EXPAND]); } /** * gtk_column_view_column_get_expand: (attributes org.gtk.Method.get_property=expand) * @self: a `GtkColumnViewColumn` * * Returns whether this column should expand. * * Returns: %TRUE if this column expands */ gboolean gtk_column_view_column_get_expand (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), TRUE); return self->expand; } /** * gtk_column_view_column_set_resizable: (attributes org.gtk.Method.set_property=resizable) * @self: a `GtkColumnViewColumn` * @resizable: whether this column should be resizable * * Sets whether this column should be resizable by dragging. */ void gtk_column_view_column_set_resizable (GtkColumnViewColumn *self, gboolean resizable) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); if (self->resizable == resizable) return; self->resizable = resizable; g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_RESIZABLE]); } /** * gtk_column_view_column_get_resizable: (attributes org.gtk.Method.get_property=resizable) * @self: a `GtkColumnViewColumn` * * Returns whether this column is resizable. * * Returns: %TRUE if this column is resizable */ gboolean gtk_column_view_column_get_resizable (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), TRUE); return self->resizable; } /** * gtk_column_view_column_set_fixed_width: (attributes org.gtk.Method.set_property=fixed-width) * @self: a `GtkColumnViewColumn` * @fixed_width: the new fixed width, or -1 * * If @fixed_width is not -1, sets the fixed width of @column; * otherwise unsets it. * * Setting a fixed width overrides the automatically calculated * width. Interactive resizing also sets the “fixed-width” property. */ void gtk_column_view_column_set_fixed_width (GtkColumnViewColumn *self, int fixed_width) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); g_return_if_fail (fixed_width >= -1); if (self->fixed_width == fixed_width) return; self->fixed_width = fixed_width; gtk_column_view_column_queue_resize (self); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_FIXED_WIDTH]); } /** * gtk_column_view_column_get_fixed_width: (attributes org.gtk.Method.get_property=fixed-width) * @self: a `GtkColumnViewColumn` * * Gets the fixed width of the column. * * Returns: the fixed with of the column */ int gtk_column_view_column_get_fixed_width (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), -1); return self->fixed_width; } GtkWidget * gtk_column_view_column_get_header (GtkColumnViewColumn *self) { return self->header; } void gtk_column_view_column_set_header_position (GtkColumnViewColumn *self, int offset) { self->header_position = offset; } void gtk_column_view_column_get_header_allocation (GtkColumnViewColumn *self, int *offset, int *size) { if (offset) *offset = self->header_position; if (size) *size = self->allocation_size; } /** * gtk_column_view_column_set_id: (attributes org.gtk.Method.set_property=id) * @self: a `GtkColumnViewColumn` * @id: (nullable): ID to use for this column * * Sets the id of this column. * * GTK makes no use of this, but applications can use it when * storing column view configuration. * * It is up to callers to ensure uniqueness of IDs. * * Since: 4.10 */ void gtk_column_view_column_set_id (GtkColumnViewColumn *self, const char *id) { g_return_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self)); if (g_strcmp0 (self->id, id) == 0) return; g_free (self->id); self->id = g_strdup (id); g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_ID]); } /** * gtk_column_view_column_get_id: (attributes org.gtk.Method.get_property=id) * @self: a `GtkColumnViewColumn` * * Returns the ID set with gtk_column_view_column_set_id(). * * Returns: (nullable): The column's ID * * Since: 4.10 */ const char * gtk_column_view_column_get_id (GtkColumnViewColumn *self) { g_return_val_if_fail (GTK_IS_COLUMN_VIEW_COLUMN (self), NULL); return self->id; }