From ba429d344132c088177e853cce8ff7181570b221 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 10 Apr 2024 19:42:51 +0200 Subject: Adding upstream version 44.2. Signed-off-by: Daniel Baumann --- subprojects/libgd/libgd/gd-main-box.c | 548 ++++++++++++++++++++++++++++++++++ 1 file changed, 548 insertions(+) create mode 100644 subprojects/libgd/libgd/gd-main-box.c (limited to 'subprojects/libgd/libgd/gd-main-box.c') diff --git a/subprojects/libgd/libgd/gd-main-box.c b/subprojects/libgd/libgd/gd-main-box.c new file mode 100644 index 0000000..be87b1d --- /dev/null +++ b/subprojects/libgd/libgd/gd-main-box.c @@ -0,0 +1,548 @@ +/* + * Copyright (c) 2016, 2017 Red Hat, Inc. + * + * This program 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 of the License, or (at your + * option) any later version. + * + * This program 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 program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: Debarshi Ray + * + */ + +#include "gd-main-box.h" +#include "gd-main-box-child.h" +#include "gd-main-box-generic.h" +#include "gd-main-icon-box.h" + +#define MAIN_BOX_TYPE_INITIAL -1 + +typedef struct _GdMainBoxPrivate GdMainBoxPrivate; + +struct _GdMainBoxPrivate +{ + GListModel *model; + GdMainBoxType current_type; + GtkWidget *current_box; + GtkWidget *frame; + gboolean selection_mode; + gboolean show_primary_text; + gboolean show_secondary_text; +}; + +enum +{ + PROP_BOX_TYPE = 1, + PROP_SELECTION_MODE, + PROP_SHOW_PRIMARY_TEXT, + PROP_SHOW_SECONDARY_TEXT, + PROP_MODEL, + NUM_PROPERTIES +}; + +enum +{ + ITEM_ACTIVATED, + SELECTION_CHANGED, + SELECTION_MODE_REQUEST, + NUM_SIGNALS +}; + +static GParamSpec *properties[NUM_PROPERTIES] = { NULL, }; +static guint signals[NUM_SIGNALS] = { 0, }; + +G_DEFINE_TYPE_WITH_PRIVATE (GdMainBox, gd_main_box, GTK_TYPE_BIN) + +static void +gd_main_box_activate_item_for_child (GdMainBox *self, GdMainBoxChild *child) +{ + GdMainBoxPrivate *priv; + GdMainBoxItem *item; + + priv = gd_main_box_get_instance_private (self); + + if (priv->model == NULL) + return; + + item = gd_main_box_child_get_item (child); + if (item == NULL) + return; + + g_signal_emit (self, signals[ITEM_ACTIVATED], 0, item); +} + +static void +gd_main_box_apply_selection_mode (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + gd_main_box_generic_set_selection_mode (GD_MAIN_BOX_GENERIC (priv->current_box), priv->selection_mode); + + if (!priv->selection_mode) + { + if (priv->model != NULL) + gd_main_box_unselect_all (self); + } +} + +static void +gd_main_box_item_activated_cb (GdMainBox *self, GdMainBoxChild *child) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (!priv->selection_mode) + gd_main_box_activate_item_for_child (self, child); +} + +static void +gd_main_box_selection_changed_cb (GdMainBox *self) +{ + g_signal_emit (self, signals[SELECTION_CHANGED], 0); +} + +static void +gd_main_box_selection_mode_request_cb (GdMainBox *self) +{ + g_signal_emit (self, signals[SELECTION_MODE_REQUEST], 0); +} + +static void +gd_main_box_rebuild (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (priv->current_box != NULL) + gtk_widget_destroy (priv->current_box); + + switch (priv->current_type) + { + case GD_MAIN_BOX_ICON: + priv->current_box = gd_main_icon_box_new (); + break; + + case GD_MAIN_BOX_LIST: + default: + g_assert_not_reached (); + break; + } + + gtk_widget_set_hexpand (priv->current_box, TRUE); + gtk_widget_set_valign (priv->current_box, GTK_ALIGN_START); + g_object_bind_property (self, "show-primary-text", + priv->current_box, "show-primary-text", + G_BINDING_SYNC_CREATE); + g_object_bind_property (self, "show-secondary-text", + priv->current_box, "show-secondary-text", + G_BINDING_SYNC_CREATE); + gtk_container_add (GTK_CONTAINER (priv->frame), priv->current_box); + + g_signal_connect_swapped (priv->current_box, + "item-activated", + G_CALLBACK (gd_main_box_item_activated_cb), + self); + g_signal_connect_swapped (priv->current_box, + "selection-changed", + G_CALLBACK (gd_main_box_selection_changed_cb), + self); + g_signal_connect_swapped (priv->current_box, + "selection-mode-request", + G_CALLBACK (gd_main_box_selection_mode_request_cb), + self); + + gd_main_box_generic_set_model (GD_MAIN_BOX_GENERIC (priv->current_box), priv->model); + gd_main_box_apply_selection_mode (self); + + gtk_widget_show_all (GTK_WIDGET (self)); +} + +static void +gd_main_box_dispose (GObject *obj) +{ + GdMainBox *self = GD_MAIN_BOX (obj); + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + g_clear_object (&priv->model); + + G_OBJECT_CLASS (gd_main_box_parent_class)->dispose (obj); +} + +static void +gd_main_box_init (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + GtkStyleContext *context; + + priv = gd_main_box_get_instance_private (self); + + priv->frame = gtk_frame_new (NULL); + context = gtk_widget_get_style_context (priv->frame); + gtk_style_context_add_class (context, "content-view"); + gtk_container_add (GTK_CONTAINER (self), priv->frame); + + /* so that we get constructed with the right view even at startup */ + priv->current_type = MAIN_BOX_TYPE_INITIAL; +} + +static void +gd_main_box_get_property (GObject *object, guint property_id, GValue *value, GParamSpec *pspec) +{ + GdMainBox *self = GD_MAIN_BOX (object); + + switch (property_id) + { + case PROP_BOX_TYPE: + g_value_set_int (value, gd_main_box_get_box_type (self)); + break; + case PROP_SELECTION_MODE: + g_value_set_boolean (value, gd_main_box_get_selection_mode (self)); + break; + case PROP_SHOW_PRIMARY_TEXT: + g_value_set_boolean (value, gd_main_box_get_show_primary_text (self)); + break; + case PROP_SHOW_SECONDARY_TEXT: + g_value_set_boolean (value, gd_main_box_get_show_secondary_text (self)); + break; + case PROP_MODEL: + g_value_set_object (value, gd_main_box_get_model (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gd_main_box_set_property (GObject *object, guint property_id, const GValue *value, GParamSpec *pspec) +{ + GdMainBox *self = GD_MAIN_BOX (object); + + switch (property_id) + { + case PROP_BOX_TYPE: + gd_main_box_set_box_type (self, g_value_get_int (value)); + break; + case PROP_SELECTION_MODE: + gd_main_box_set_selection_mode (self, g_value_get_boolean (value)); + break; + case PROP_SHOW_PRIMARY_TEXT: + gd_main_box_set_show_primary_text (self, g_value_get_boolean (value)); + break; + case PROP_SHOW_SECONDARY_TEXT: + gd_main_box_set_show_secondary_text (self, g_value_get_boolean (value)); + break; + case PROP_MODEL: + gd_main_box_set_model (self, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); + break; + } +} + +static void +gd_main_box_class_init (GdMainBoxClass *klass) +{ + GObjectClass *oclass = G_OBJECT_CLASS (klass); + + oclass->get_property = gd_main_box_get_property; + oclass->set_property = gd_main_box_set_property; + oclass->dispose = gd_main_box_dispose; + + properties[PROP_BOX_TYPE] = g_param_spec_int ("box-type", + "Box type", + "Box type", + GD_MAIN_BOX_ICON, + GD_MAIN_BOX_LIST, + GD_MAIN_BOX_ICON, + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + properties[PROP_MODEL] = g_param_spec_object ("model", + "Model", + "The GListModel", + G_TYPE_LIST_MODEL, + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + properties[PROP_SELECTION_MODE] = g_param_spec_boolean ("selection-mode", + "Selection mode", + "Whether the view is in selection mode", + FALSE, + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + properties[PROP_SHOW_PRIMARY_TEXT] = g_param_spec_boolean ("show-primary-text", + "Show primary text", + "Whether each GdMainBoxItem's primary-text is going " + "to be shown", + FALSE, + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + properties[PROP_SHOW_SECONDARY_TEXT] = g_param_spec_boolean ("show-secondary-text", + "Show secondary text", + "Whether each GdMainBoxItem's secondary-text is " + "going to be shown", + FALSE, + G_PARAM_EXPLICIT_NOTIFY | + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS); + + signals[ITEM_ACTIVATED] = g_signal_new ("item-activated", + GD_TYPE_MAIN_BOX, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, + 1, + GD_TYPE_MAIN_BOX_ITEM); + + signals[SELECTION_CHANGED] = g_signal_new ("selection-changed", + GD_TYPE_MAIN_BOX, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + signals[SELECTION_MODE_REQUEST] = g_signal_new ("selection-mode-request", + GD_TYPE_MAIN_BOX, + G_SIGNAL_RUN_LAST, + 0, + NULL, + NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, + 0); + + g_object_class_install_properties (oclass, NUM_PROPERTIES, properties); +} + +GtkWidget * +gd_main_box_new (GdMainBoxType type) +{ + return g_object_new (GD_TYPE_MAIN_BOX, "box-type", type, NULL); +} + +GdMainBoxType +gd_main_box_get_box_type (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->current_type; +} + +void +gd_main_box_set_box_type (GdMainBox *self, GdMainBoxType type) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (type == priv->current_type) + return; + + priv->current_type = type; + gd_main_box_rebuild (self); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_BOX_TYPE]); +} + +gboolean +gd_main_box_get_selection_mode (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->selection_mode; +} + +gboolean +gd_main_box_get_show_primary_text (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->show_primary_text; +} + +gboolean +gd_main_box_get_show_secondary_text (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->show_secondary_text; +} + +void +gd_main_box_set_selection_mode (GdMainBox *self, gboolean selection_mode) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (selection_mode == priv->selection_mode) + return; + + priv->selection_mode = selection_mode; + gd_main_box_apply_selection_mode (self); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SELECTION_MODE]); +} + +void +gd_main_box_set_show_primary_text (GdMainBox *self, gboolean show_primary_text) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (show_primary_text == priv->show_primary_text) + return; + + priv->show_primary_text = show_primary_text; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_PRIMARY_TEXT]); +} + +void +gd_main_box_set_show_secondary_text (GdMainBox *self, gboolean show_secondary_text) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (show_secondary_text == priv->show_secondary_text) + return; + + priv->show_secondary_text = show_secondary_text; + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_SHOW_SECONDARY_TEXT]); +} + +/** + * gd_main_box_get_model: + * @self: + * + * Returns: (transfer none): + */ +GListModel * +gd_main_box_get_model (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->model; +} + +/** + * gd_main_box_set_model: + * @self: + * @model: (allow-none): + * + */ +void +gd_main_box_set_model (GdMainBox *self, GListModel *model) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + + if (!g_set_object (&priv->model, model)) + return; + + gd_main_box_generic_set_model (GD_MAIN_BOX_GENERIC (priv->current_box), priv->model); + g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_MODEL]); +} + +/** + * gd_main_box_get_generic_box: + * @self: + * + * Returns: (transfer none): + */ +GtkWidget * +gd_main_box_get_generic_box (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + return priv->current_box; +} + +/** + * gd_main_box_get_selection: + * @self: + * + * Returns: (element-type GdMainBoxItem) (transfer full): + */ +GList * +gd_main_box_get_selection (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + GList *l; + GList *selected_children; + GList *selection = NULL; + + priv = gd_main_box_get_instance_private (self); + + selected_children = gd_main_box_generic_get_selected_children (GD_MAIN_BOX_GENERIC (priv->current_box)); + for (l = selected_children; l != NULL; l = l->next) + { + GdMainBoxChild *child = GD_MAIN_BOX_CHILD (l->data); + GdMainBoxItem *item; + + item = gd_main_box_child_get_item (child); + selection = g_list_prepend (selection, g_object_ref (item)); + } + + selection = g_list_reverse (selection); + g_list_free (selected_children); + return selection; +} + +void +gd_main_box_select_all (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + gd_main_box_generic_select_all (GD_MAIN_BOX_GENERIC (priv->current_box)); +} + +void +gd_main_box_unselect_all (GdMainBox *self) +{ + GdMainBoxPrivate *priv; + + priv = gd_main_box_get_instance_private (self); + gd_main_box_generic_unselect_all (GD_MAIN_BOX_GENERIC (priv->current_box)); +} -- cgit v1.2.3