diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:57:27 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 17:57:27 +0000 |
commit | 6f0f7d1b40a8fa8d46a2d6f4317600001cdbbb18 (patch) | |
tree | d423850ae901365e582137bdf2b5cbdffd7ca266 /src/gs-app-tile.c | |
parent | Initial commit. (diff) | |
download | gnome-software-6f0f7d1b40a8fa8d46a2d6f4317600001cdbbb18.tar.xz gnome-software-6f0f7d1b40a8fa8d46a2d6f4317600001cdbbb18.zip |
Adding upstream version 43.5.upstream/43.5upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/gs-app-tile.c')
-rw-r--r-- | src/gs-app-tile.c | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/src/gs-app-tile.c b/src/gs-app-tile.c new file mode 100644 index 0000000..01449a7 --- /dev/null +++ b/src/gs-app-tile.c @@ -0,0 +1,176 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2013 Matthias Clasen <mclasen@redhat.com> + * Copyright (C) 2019 Richard Hughes <richard@hughsie.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include "gs-app-tile.h" +#include "gs-common.h" + +typedef struct { + GsApp *app; + guint app_notify_idle_id; +} GsAppTilePrivate; + +G_DEFINE_ABSTRACT_TYPE_WITH_PRIVATE (GsAppTile, gs_app_tile, GTK_TYPE_BUTTON) + +typedef enum { + PROP_APP = 1, +} GsAppTileProperty; + +static GParamSpec *obj_props[PROP_APP + 1] = { NULL, }; + +static void +gs_app_tile_get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec) +{ + GsAppTile *self = GS_APP_TILE (object); + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + + switch ((GsAppTileProperty) prop_id) { + case PROP_APP: + g_value_set_object (value, priv->app); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_app_tile_set_property (GObject *object, guint prop_id, const GValue *value, GParamSpec *pspec) +{ + GsAppTile *self = GS_APP_TILE (object); + + switch ((GsAppTileProperty) prop_id) { + case PROP_APP: + gs_app_tile_set_app (self, g_value_get_object (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_app_tile_dispose (GObject *object) +{ + GsAppTile *self = GS_APP_TILE (object); + + gs_app_tile_set_app (self, NULL); + + G_OBJECT_CLASS (gs_app_tile_parent_class)->dispose (object); +} + +/** + * gs_app_tile_get_app: + * @self: a #GsAppTile + * + * Get the value of #GsAppTile:app. + * + * Returns: (nullable) (transfer none): the #GsAppTile:app property + */ +GsApp * +gs_app_tile_get_app (GsAppTile *self) +{ + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + g_return_val_if_fail (GS_IS_APP_TILE (self), NULL); + return priv->app; +} + +static gboolean +gs_app_tile_app_notify_idle_cb (gpointer user_data) +{ + GsAppTile *self = GS_APP_TILE (user_data); + GsAppTileClass *klass = GS_APP_TILE_GET_CLASS (self); + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + + priv->app_notify_idle_id = 0; + klass->refresh (self); + + return G_SOURCE_REMOVE; +} + +static void +gs_app_tile_app_notify_cb (GsApp *app, GParamSpec *pspec, GsAppTile *self) +{ + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + + /* Already pending */ + if (priv->app_notify_idle_id != 0) + return; + + priv->app_notify_idle_id = g_idle_add (gs_app_tile_app_notify_idle_cb, self); +} + +/** + * gs_app_tile_set_app: + * @self: a #GsAppTile + * @app: (transfer none) (nullable): the new value for #GsAppTile:app + * + * Set the value of #GsAppTile:app. + */ +void +gs_app_tile_set_app (GsAppTile *self, GsApp *app) +{ + GsAppTileClass *klass = GS_APP_TILE_GET_CLASS (self); + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + + g_return_if_fail (GS_IS_APP_TILE (self)); + g_return_if_fail (!app || GS_IS_APP (app)); + + /* cancel pending refresh */ + g_clear_handle_id (&priv->app_notify_idle_id, g_source_remove); + + /* disconnect old app */ + if (priv->app != NULL) + g_signal_handlers_disconnect_by_func (priv->app, gs_app_tile_app_notify_cb, self); + g_set_object (&priv->app, app); + + /* optional refresh */ + if (klass->refresh != NULL && priv->app != NULL) { + g_signal_connect (app, "notify", + G_CALLBACK (gs_app_tile_app_notify_cb), self); + klass->refresh (self); + } + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_APP]); +} + +void +gs_app_tile_class_init (GsAppTileClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + object_class->get_property = gs_app_tile_get_property; + object_class->set_property = gs_app_tile_set_property; + object_class->dispose = gs_app_tile_dispose; + + /** + * GsAppTile:app: (nullable) + * + * The app to display in this tile. + * + * Set this to %NULL to display a loading/empty tile. + * + * Since: 41 + */ + obj_props[PROP_APP] = + g_param_spec_object ("app", "App", + "The app to display in this tile.", + GS_TYPE_APP, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + g_object_class_install_properties (object_class, G_N_ELEMENTS (obj_props), obj_props); +} + +void +gs_app_tile_init (GsAppTile *self) +{ + GsAppTilePrivate *priv = gs_app_tile_get_instance_private (self); + priv->app_notify_idle_id = 0; +} |