diff --git a/src/gnome-software.gresource.xml b/src/gnome-software.gresource.xml index 6b58f2e616c9a01675ce22a577430062dda2710a..60277a60022aaf572053e058c8547815c175c628 100644 --- a/src/gnome-software.gresource.xml +++ b/src/gnome-software.gresource.xml @@ -24,6 +24,7 @@ gs-installed-page.ui gs-license-tile.ui gs-loading-page.ui + gs-lozenge.ui gs-metered-data-dialog.ui gs-moderate-page.ui gs-overview-page.ui diff --git a/src/gs-age-rating-context-dialog.c b/src/gs-age-rating-context-dialog.c index 090c0b542615307cf9762d49471133ff839f4ab5..52a617e7d34dbd2a62f21ea9ec1765fbf636059e 100644 --- a/src/gs-age-rating-context-dialog.c +++ b/src/gs-age-rating-context-dialog.c @@ -70,8 +70,7 @@ struct _GsAgeRatingContextDialog GsContextDialogRow *rows[GS_AGE_RATING_GROUP_TYPE_COUNT]; /* (unowned) */ GList *attributes[GS_AGE_RATING_GROUP_TYPE_COUNT]; /* (element-type GsAgeRatingAttribute) */ - GtkLabel *age; - GtkWidget *lozenge; + GsLozenge *lozenge; GtkLabel *title; GtkListBox *attributes_list; /* (element-type GsContextDialogRow) */ }; @@ -878,15 +877,13 @@ gs_age_rating_context_dialog_format_age_short (AsContentRatingSystem system, /** * gs_age_rating_context_dialog_update_lozenge: * @app: the #GsApp to rate - * @lozenge: lozenge widget - * @lozenge_content: label within the lozenge widget + * @lozenge: a #GsLozenge widget * @is_unknown_out: (out caller-allocates) (not optional): return location for * a boolean indicating whether the age rating is unknown, rather than a * specific age * - * Update the @lozenge and @lozenge_content widgets to indicate the overall - * age rating for @app. This involves changing their CSS class and label - * content. + * Update the @lozenge widget to indicate the overall age rating for @app. + * This involves changing its CSS class and label content. * * If the overall age rating for @app is unknown (because the app doesn’t * provide a complete `` element in its appdata), the lozenge is @@ -896,8 +893,7 @@ gs_age_rating_context_dialog_format_age_short (AsContentRatingSystem system, */ void gs_age_rating_context_dialog_update_lozenge (GsApp *app, - GtkWidget *lozenge, - GtkLabel *lozenge_content, + GsLozenge *lozenge, gboolean *is_unknown_out) { const gchar *css_class; @@ -916,8 +912,7 @@ gs_age_rating_context_dialog_update_lozenge (GsApp *app, g_autofree gchar *age_text = NULL; g_return_if_fail (GS_IS_APP (app)); - g_return_if_fail (GTK_IS_WIDGET (lozenge)); - g_return_if_fail (GTK_IS_LABEL (lozenge_content)); + g_return_if_fail (GS_IS_LOZENGE (lozenge)); g_return_if_fail (is_unknown_out != NULL); /* get the content rating system from the locale */ @@ -971,9 +966,9 @@ gs_age_rating_context_dialog_update_lozenge (GsApp *app, } /* Update the UI. */ - gtk_label_set_text (lozenge_content, age_text); + gs_lozenge_set_text (lozenge, age_text); - context = gtk_widget_get_style_context (lozenge); + context = gtk_widget_get_style_context (GTK_WIDGET (lozenge)); for (gsize i = 0; i < G_N_ELEMENTS (css_age_classes); i++) gtk_style_context_remove_class (context, css_age_classes[i]); @@ -1008,7 +1003,6 @@ update_attributes_list (GsAgeRatingContextDialog *self) content_rating = gs_app_dup_content_rating (self->app); gs_age_rating_context_dialog_update_lozenge (self->app, self->lozenge, - self->age, &is_unknown); /* Title */ @@ -1052,7 +1046,7 @@ update_attributes_list (GsAgeRatingContextDialog *self) * for a specified age group. The first placeholder is the app name, the second * is the age group. */ title = g_strdup_printf (_("%s is suitable for %s"), gs_app_get_name (self->app), - gtk_label_get_text (self->age)); + gs_lozenge_get_text (self->lozenge)); } gtk_label_set_text (self->title, title); @@ -1180,7 +1174,6 @@ gs_age_rating_context_dialog_class_init (GsAgeRatingContextDialogClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-age-rating-context-dialog.ui"); - gtk_widget_class_bind_template_child (widget_class, GsAgeRatingContextDialog, age); gtk_widget_class_bind_template_child (widget_class, GsAgeRatingContextDialog, lozenge); gtk_widget_class_bind_template_child (widget_class, GsAgeRatingContextDialog, title); gtk_widget_class_bind_template_child (widget_class, GsAgeRatingContextDialog, attributes_list); diff --git a/src/gs-age-rating-context-dialog.h b/src/gs-age-rating-context-dialog.h index 38902f83b870b0b2ad37650a39047d6cd092ab57..f619004161e2801bc04e9eaf28e004f8dda7fd18 100644 --- a/src/gs-age-rating-context-dialog.h +++ b/src/gs-age-rating-context-dialog.h @@ -16,6 +16,7 @@ #include "gs-app.h" #include "gs-info-window.h" +#include "gs-lozenge.h" G_BEGIN_DECLS @@ -32,8 +33,7 @@ void gs_age_rating_context_dialog_set_app (GsAgeRatingContextDialog *self, gchar *gs_age_rating_context_dialog_format_age_short (AsContentRatingSystem system, guint age); void gs_age_rating_context_dialog_update_lozenge (GsApp *app, - GtkWidget *lozenge, - GtkLabel *lozenge_content, + GsLozenge *lozenge, gboolean *is_unknown_out); diff --git a/src/gs-age-rating-context-dialog.ui b/src/gs-age-rating-context-dialog.ui index 9ac2b705fb14f25d73e423de6dd09078290be6b6..0572fc45e78b083b4bc051cbddacf74a0b71572c 100644 --- a/src/gs-age-rating-context-dialog.ui +++ b/src/gs-age-rating-context-dialog.ui @@ -23,25 +23,15 @@ 12 - - center + + True - - - center - True - - All - 0.5 - - title - - - + + title + diff --git a/src/gs-app-context-bar.c b/src/gs-app-context-bar.c index d7ea20449b53672bf2de92df34aa63e29760898f..9b9cad5cac147bb3855614b9ab07cbfad860ac7d 100644 --- a/src/gs-app-context-bar.c +++ b/src/gs-app-context-bar.c @@ -38,6 +38,7 @@ #include "gs-app-context-bar.h" #include "gs-common.h" #include "gs-hardware-support-context-dialog.h" +#include "gs-lozenge.h" #include "gs-safety-context-dialog.h" #include "gs-storage-context-dialog.h" @@ -45,7 +46,6 @@ typedef struct { GtkWidget *tile; GtkWidget *lozenge; - GtkWidget *lozenge_content; GtkLabel *title; GtkLabel *description; } GsAppContextTile; @@ -215,9 +215,9 @@ update_storage_tile (GsAppContextBar *self) } if (lozenge_text_is_markup) - gtk_label_set_markup (GTK_LABEL (self->tiles[STORAGE_TILE].lozenge_content), lozenge_text); + gs_lozenge_set_markup (GS_LOZENGE (self->tiles[STORAGE_TILE].lozenge), lozenge_text); else - gtk_label_set_text (GTK_LABEL (self->tiles[STORAGE_TILE].lozenge_content), lozenge_text); + gs_lozenge_set_text (GS_LOZENGE (self->tiles[STORAGE_TILE].lozenge), lozenge_text); gtk_label_set_text (self->tiles[STORAGE_TILE].title, title); gtk_label_set_text (self->tiles[STORAGE_TILE].description, description); } @@ -482,7 +482,7 @@ update_safety_tile (GsAppContextBar *self) g_assert_not_reached (); } - gtk_image_set_from_icon_name (GTK_IMAGE (self->tiles[SAFETY_TILE].lozenge_content), icon_name); + gs_lozenge_set_icon_name (GS_LOZENGE (self->tiles[SAFETY_TILE].lozenge), icon_name); gtk_label_set_text (self->tiles[SAFETY_TILE].title, title); gtk_label_set_text (self->tiles[SAFETY_TILE].description, description); @@ -654,8 +654,8 @@ update_hardware_support_tile (GsAppContextBar *self) /* Update the UI. The `adaptive-symbolic` icon needs a special size to * be set, as it is wider than it is tall. Setting the size ensures it’s * rendered at the right height. */ - gtk_image_set_from_icon_name (GTK_IMAGE (self->tiles[HARDWARE_SUPPORT_TILE].lozenge_content), icon_name); - gtk_image_set_pixel_size (GTK_IMAGE (self->tiles[HARDWARE_SUPPORT_TILE].lozenge_content), g_str_equal (icon_name, "adaptive-symbolic") ? 56 : -1); + gs_lozenge_set_icon_name (GS_LOZENGE (self->tiles[HARDWARE_SUPPORT_TILE].lozenge), icon_name); + gs_lozenge_set_pixel_size (GS_LOZENGE (self->tiles[HARDWARE_SUPPORT_TILE].lozenge), g_str_equal (icon_name, "adaptive-symbolic") ? 56 : -1); gtk_label_set_text (self->tiles[HARDWARE_SUPPORT_TILE].title, title); gtk_label_set_text (self->tiles[HARDWARE_SUPPORT_TILE].description, description); @@ -732,8 +732,7 @@ update_age_rating_tile (GsAppContextBar *self) content_rating = gs_app_dup_content_rating (self->app); gs_age_rating_context_dialog_update_lozenge (self->app, - self->tiles[AGE_RATING_TILE].lozenge, - GTK_LABEL (self->tiles[AGE_RATING_TILE].lozenge_content), + GS_LOZENGE (self->tiles[AGE_RATING_TILE].lozenge), &is_unknown); /* Description */ @@ -885,22 +884,18 @@ gs_app_context_bar_class_init (GsAppContextBarClass *klass) gtk_widget_class_bind_template_child_full (widget_class, "storage_tile", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[STORAGE_TILE].tile)); gtk_widget_class_bind_template_child_full (widget_class, "storage_tile_lozenge", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[STORAGE_TILE].lozenge)); - gtk_widget_class_bind_template_child_full (widget_class, "storage_tile_lozenge_content", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[STORAGE_TILE].lozenge_content)); gtk_widget_class_bind_template_child_full (widget_class, "storage_tile_title", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[STORAGE_TILE].title)); gtk_widget_class_bind_template_child_full (widget_class, "storage_tile_description", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[STORAGE_TILE].description)); gtk_widget_class_bind_template_child_full (widget_class, "safety_tile", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[SAFETY_TILE].tile)); gtk_widget_class_bind_template_child_full (widget_class, "safety_tile_lozenge", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[SAFETY_TILE].lozenge)); - gtk_widget_class_bind_template_child_full (widget_class, "safety_tile_lozenge_content", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[SAFETY_TILE].lozenge_content)); gtk_widget_class_bind_template_child_full (widget_class, "safety_tile_title", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[SAFETY_TILE].title)); gtk_widget_class_bind_template_child_full (widget_class, "safety_tile_description", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[SAFETY_TILE].description)); gtk_widget_class_bind_template_child_full (widget_class, "hardware_support_tile", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[HARDWARE_SUPPORT_TILE].tile)); gtk_widget_class_bind_template_child_full (widget_class, "hardware_support_tile_lozenge", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[HARDWARE_SUPPORT_TILE].lozenge)); - gtk_widget_class_bind_template_child_full (widget_class, "hardware_support_tile_lozenge_content", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[HARDWARE_SUPPORT_TILE].lozenge_content)); gtk_widget_class_bind_template_child_full (widget_class, "hardware_support_tile_title", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[HARDWARE_SUPPORT_TILE].title)); gtk_widget_class_bind_template_child_full (widget_class, "hardware_support_tile_description", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[HARDWARE_SUPPORT_TILE].description)); gtk_widget_class_bind_template_child_full (widget_class, "age_rating_tile", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[AGE_RATING_TILE].tile)); gtk_widget_class_bind_template_child_full (widget_class, "age_rating_tile_lozenge", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[AGE_RATING_TILE].lozenge)); - gtk_widget_class_bind_template_child_full (widget_class, "age_rating_tile_lozenge_content", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[AGE_RATING_TILE].lozenge_content)); gtk_widget_class_bind_template_child_full (widget_class, "age_rating_tile_title", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[AGE_RATING_TILE].title)); gtk_widget_class_bind_template_child_full (widget_class, "age_rating_tile_description", FALSE, G_STRUCT_OFFSET (GsAppContextBar, tiles[AGE_RATING_TILE].description)); gtk_widget_class_bind_template_callback (widget_class, tile_clicked_cb); diff --git a/src/gs-app-context-bar.ui b/src/gs-app-context-bar.ui index 705d7dcdb3b0cd1d54a538980efd6face5bf4ceb..db7091283b9c121cfdb860c6960d47eff432d91f 100644 --- a/src/gs-app-context-bar.ui +++ b/src/gs-app-context-bar.ui @@ -24,25 +24,15 @@ vertical 8 - - center + + False - - - center - True - - 20 MB - 0.5 - - storage_tile_title - storage_tile_description - - - + + storage_tile_title + storage_tile_description + @@ -86,24 +76,17 @@ vertical 8 - - center + + True + + safety-symbolic - - - center - True - - safety-symbolic - - safety_tile_title - safety_tile_description - - - + + safety_tile_title + safety_tile_description + @@ -154,26 +137,19 @@ vertical 8 - - center + + False + + adaptive-symbolic + 56 - - - center - True - - adaptive-symbolic - 56 - - hardware_support_tile_title - hardware_support_tile_description - - - + + hardware_support_tile_title + hardware_support_tile_description + @@ -217,25 +193,15 @@ vertical 8 - - center + + True - - - center - True - - 18+ - 0.5 - - age_rating_tile_title - age_rating_tile_description - - - + + age_rating_tile_title + age_rating_tile_description + diff --git a/src/gs-app-translation-dialog.ui b/src/gs-app-translation-dialog.ui index 18b608ccfd38d8ca1c310efd3aa8e5859e807665..4b5b41f31e9f6bfab5ec3dac96f903485721a6c5 100644 --- a/src/gs-app-translation-dialog.ui +++ b/src/gs-app-translation-dialog.ui @@ -27,24 +27,17 @@ 12 - - center + + True + flag-outline-thin-symbolic + 24 - - - center - True - flag-outline-thin-symbolic - 24 - - title - - - + + title + diff --git a/src/gs-context-dialog-row.c b/src/gs-context-dialog-row.c index 11c9f382264e7db9ce03d98c442799f4dfee022b..73f8fcbfc2203f5bbd7e850a2e7f851ef187ee89 100644 --- a/src/gs-context-dialog-row.c +++ b/src/gs-context-dialog-row.c @@ -30,6 +30,7 @@ #include #include "gs-context-dialog-row.h" +#include "gs-lozenge.h" #include "gs-enums.h" struct _GsContextDialogRow @@ -38,9 +39,7 @@ struct _GsContextDialogRow GsContextDialogRowImportance importance; - GtkWidget *lozenge; /* (unowned) */ - GtkImage *lozenge_content_image; /* (unowned) */ - GtkLabel *lozenge_content_text; /* (unowned) */ + GsLozenge *lozenge; /* (unowned) */ }; G_DEFINE_TYPE (GsContextDialogRow, gs_context_dialog_row, ADW_TYPE_ACTION_ROW) @@ -111,14 +110,10 @@ gs_context_dialog_row_set_property (GObject *object, switch ((GsContextDialogRowProperty) prop_id) { case PROP_ICON_NAME: - gtk_image_set_from_icon_name (self->lozenge_content_image, g_value_get_string (value)); - gtk_widget_set_visible (GTK_WIDGET (self->lozenge_content_image), TRUE); - gtk_widget_set_visible (GTK_WIDGET (self->lozenge_content_text), FALSE); + gs_lozenge_set_icon_name (self->lozenge, g_value_get_string (value)); break; case PROP_CONTENT: - gtk_label_set_text (self->lozenge_content_text, g_value_get_string (value)); - gtk_widget_set_visible (GTK_WIDGET (self->lozenge_content_image), FALSE); - gtk_widget_set_visible (GTK_WIDGET (self->lozenge_content_text), TRUE); + gs_lozenge_set_text (self->lozenge, g_value_get_string (value)); break; case PROP_IMPORTANCE: { GtkStyleContext *context; @@ -127,7 +122,7 @@ gs_context_dialog_row_set_property (GObject *object, self->importance = g_value_get_enum (value); css_class = css_class_for_importance (self->importance); - context = gtk_widget_get_style_context (self->lozenge); + context = gtk_widget_get_style_context (GTK_WIDGET (self->lozenge)); gtk_style_context_remove_class (context, "green"); gtk_style_context_remove_class (context, "yellow"); @@ -204,8 +199,6 @@ gs_context_dialog_row_class_init (GsContextDialogRowClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-context-dialog-row.ui"); gtk_widget_class_bind_template_child (widget_class, GsContextDialogRow, lozenge); - gtk_widget_class_bind_template_child (widget_class, GsContextDialogRow, lozenge_content_image); - gtk_widget_class_bind_template_child (widget_class, GsContextDialogRow, lozenge_content_text); } /** @@ -282,7 +275,7 @@ gs_context_dialog_row_get_icon_name (GsContextDialogRow *self) { g_return_val_if_fail (GS_IS_CONTEXT_DIALOG_ROW (self), NULL); - return gtk_image_get_icon_name (self->lozenge_content_image); + return gs_lozenge_get_icon_name (self->lozenge); } /** @@ -299,7 +292,7 @@ gs_context_dialog_row_get_content (GsContextDialogRow *self) { g_return_val_if_fail (GS_IS_CONTEXT_DIALOG_ROW (self), NULL); - return gtk_label_get_text (self->lozenge_content_text); + return gs_lozenge_get_text (self->lozenge); } /** @@ -316,25 +309,25 @@ gs_context_dialog_row_get_content_is_markup (GsContextDialogRow *self) { g_return_val_if_fail (GS_IS_CONTEXT_DIALOG_ROW (self), FALSE); - return gtk_label_get_use_markup (self->lozenge_content_text); + return gs_lozenge_get_use_markup (self->lozenge); } /** - * gs_context_dialog_row_set_content_is_markup: + * gs_context_dialog_row_set_content_markup: * @self: a #GsContextDialogRow - * @is_markup: value to set + * @markup: markup to set * - * Set to %TRUE, when the #GsContextDialogRow:content is markup. + * Set the @markup content as markup. * * Since: 43 */ void -gs_context_dialog_row_set_content_is_markup (GsContextDialogRow *self, - gboolean is_markup) +gs_context_dialog_row_set_content_markup (GsContextDialogRow *self, + const gchar *markup) { g_return_if_fail (GS_IS_CONTEXT_DIALOG_ROW (self)); - gtk_label_set_use_markup (self->lozenge_content_text, is_markup); + gs_lozenge_set_markup (self->lozenge, markup); } /** @@ -378,5 +371,5 @@ gs_context_dialog_row_set_size_groups (GsContextDialogRow *self, g_return_if_fail (description == NULL || GTK_IS_SIZE_GROUP (description)); if (lozenge != NULL) - gtk_size_group_add_widget (lozenge, self->lozenge); + gtk_size_group_add_widget (lozenge, GTK_WIDGET (self->lozenge)); } diff --git a/src/gs-context-dialog-row.h b/src/gs-context-dialog-row.h index 74c805918cb2c19d0d00a8b98205618bf55a7f2a..d5d68fd25debc0bf7365819e0b00b6fc48a97262 100644 --- a/src/gs-context-dialog-row.h +++ b/src/gs-context-dialog-row.h @@ -57,9 +57,9 @@ const gchar *gs_context_dialog_row_get_content (GsContextDialogRow *self); GsContextDialogRowImportance gs_context_dialog_row_get_importance (GsContextDialogRow *self); gboolean gs_context_dialog_row_get_content_is_markup (GsContextDialogRow *self); -void gs_context_dialog_row_set_content_is_markup +void gs_context_dialog_row_set_content_markup (GsContextDialogRow *self, - gboolean is_markup); + const gchar *markup); void gs_context_dialog_row_set_size_groups (GsContextDialogRow *self, GtkSizeGroup *lozenge, diff --git a/src/gs-context-dialog-row.ui b/src/gs-context-dialog-row.ui index f759f9bf1d6e83235ff3cb293e1aca0837931c63..47a78dff1432ebb3aa766c7941782bbe3b79f713 100644 --- a/src/gs-context-dialog-row.ui +++ b/src/gs-context-dialog-row.ui @@ -6,35 +6,14 @@ False - - center - center - False + + True + 16 8 8 - - - center - True - - safety-symbolic - 16 - - - - - center - True - - 20 MB - False - 0.5 - - diff --git a/src/gs-feature-tile.c b/src/gs-feature-tile.c index cff5a50679c8d024c3cfd4cab485828a8c28805c..bb8bed438f7ac6e22a879ef45eacab9cb46281b2 100644 --- a/src/gs-feature-tile.c +++ b/src/gs-feature-tile.c @@ -13,9 +13,74 @@ #include #include "gs-feature-tile.h" +#include "gs-layout-manager.h" #include "gs-common.h" #include "gs-css.h" +#define GS_TYPE_FEATURE_TILE_LAYOUT (gs_feature_tile_layout_get_type ()) +G_DECLARE_FINAL_TYPE (GsFeatureTileLayout, gs_feature_tile_layout, GS, FEATURE_TILE_LAYOUT, GsLayoutManager) + +struct _GsFeatureTileLayout +{ + GsLayoutManager parent_instance; + + gboolean narrow_mode; +}; + +G_DEFINE_TYPE (GsFeatureTileLayout, gs_feature_tile_layout, GS_TYPE_LAYOUT_MANAGER) + +enum { + SIGNAL_NARROW_MODE_CHANGED, + SIGNAL_LAST +}; + +static guint signals [SIGNAL_LAST] = { 0 }; + +static void +gs_feature_tile_layout_allocate (GtkLayoutManager *layout_manager, + GtkWidget *widget, + gint width, + gint height, + gint baseline) +{ + GsFeatureTileLayout *self = GS_FEATURE_TILE_LAYOUT (layout_manager); + gboolean narrow_mode; + + GTK_LAYOUT_MANAGER_CLASS (gs_feature_tile_layout_parent_class)->allocate (layout_manager, + widget, width, height, baseline); + + /* Engage ‘narrow mode’ if the allocation becomes too narrow. The exact + * choice of width is arbitrary here. */ + narrow_mode = (width < 600); + if (self->narrow_mode != narrow_mode) { + self->narrow_mode = narrow_mode; + g_signal_emit (self, signals[SIGNAL_NARROW_MODE_CHANGED], 0, self->narrow_mode); + } +} + +static void +gs_feature_tile_layout_class_init (GsFeatureTileLayoutClass *klass) +{ + GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + layout_manager_class->allocate = gs_feature_tile_layout_allocate; + + signals [SIGNAL_NARROW_MODE_CHANGED] = + g_signal_new ("narrow-mode-changed", + G_TYPE_FROM_CLASS (object_class), G_SIGNAL_RUN_LAST, + 0, + NULL, NULL, g_cclosure_marshal_generic, + G_TYPE_NONE, 1, G_TYPE_BOOLEAN); +} + +static void +gs_feature_tile_layout_init (GsFeatureTileLayout *self) +{ +} + +/* ********************************************************************* */ + struct _GsFeatureTile { GsAppTile parent_instance; @@ -32,54 +97,6 @@ struct _GsFeatureTile guint refresh_id; }; -#define GS_TYPE_FEATURE_TILE_LAYOUT (gs_feature_tile_layout_get_type ()) - -G_DECLARE_FINAL_TYPE (GsFeatureTileLayout, gs_feature_tile_layout, GS, FEATURE_TILE_LAYOUT, GtkLayoutManager) - -/* This is a copy of GtkBinLayout, because cannot derive from it */ -struct _GsFeatureTileLayout -{ - GtkLayoutManager parent_instance; -}; - -G_DEFINE_TYPE (GsFeatureTileLayout, gs_feature_tile_layout, GTK_TYPE_LAYOUT_MANAGER) - -static void -gs_feature_tile_layout_measure (GtkLayoutManager *layout_manager, - GtkWidget *widget, - GtkOrientation orientation, - int for_size, - int *minimum, - int *natural, - int *minimum_baseline, - int *natural_baseline) -{ - GtkWidget *child; - - for (child = gtk_widget_get_first_child (widget); - child != NULL; - child = gtk_widget_get_next_sibling (child)) { - if (gtk_widget_should_layout (child)) { - int child_min = 0; - int child_nat = 0; - int child_min_baseline = -1; - int child_nat_baseline = -1; - - gtk_widget_measure (child, orientation, for_size, - &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 gs_feature_tile_refresh (GsAppTile *self); static gboolean @@ -95,47 +112,18 @@ gs_feature_tile_refresh_idle_cb (gpointer user_data) } static void -gs_feature_tile_layout_allocate (GtkLayoutManager *layout_manager, - GtkWidget *widget, - int width, - int height, - int baseline) +gs_feature_tile_layout_narrow_mode_changed_cb (GtkLayoutManager *layout_manager, + gboolean narrow_mode, + gpointer user_data) { - GsFeatureTile *tile = GS_FEATURE_TILE (widget); - GtkWidget *child; - gboolean narrow_mode; + GsFeatureTile *self = GS_FEATURE_TILE (user_data); - for (child = gtk_widget_get_first_child (widget); - child != NULL; - child = gtk_widget_get_next_sibling (child)) { - if (child && gtk_widget_should_layout (child)) - gtk_widget_allocate (child, width, height, baseline, NULL); - } - - /* Engage ‘narrow mode’ if the allocation becomes too narrow. The exact - * choice of width is arbitrary here. */ - narrow_mode = (width < 600); - if (tile->narrow_mode != narrow_mode) { - tile->narrow_mode = narrow_mode; - if (!tile->refresh_id) - tile->refresh_id = g_idle_add (gs_feature_tile_refresh_idle_cb, tile); + if (self->narrow_mode != narrow_mode && !self->refresh_id) { + self->narrow_mode = narrow_mode; + self->refresh_id = g_idle_add (gs_feature_tile_refresh_idle_cb, self); } } -static void -gs_feature_tile_layout_class_init (GsFeatureTileLayoutClass *klass) -{ - GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); - - layout_manager_class->measure = gs_feature_tile_layout_measure; - layout_manager_class->allocate = gs_feature_tile_layout_allocate; -} - -static void -gs_feature_tile_layout_init (GsFeatureTileLayout *layout) -{ -} - /* A colour represented in hue, saturation, brightness form; with an additional * field for its contrast calculated with respect to some external colour. * @@ -588,7 +576,14 @@ gs_feature_tile_css_changed (GtkWidget *widget, static void gs_feature_tile_init (GsFeatureTile *tile) { + GtkLayoutManager *layout_manager; + gtk_widget_init_template (GTK_WIDGET (tile)); + + layout_manager = gtk_widget_get_layout_manager (GTK_WIDGET (tile)); + g_warn_if_fail (layout_manager != NULL); + g_signal_connect_object (layout_manager, "narrow-mode-changed", + G_CALLBACK (gs_feature_tile_layout_narrow_mode_changed_cb), tile, 0); } static void diff --git a/src/gs-hardware-support-context-dialog.c b/src/gs-hardware-support-context-dialog.c index e10d0c49a822aee7aee849ff79a5cca2a7f388a9..c1a4d60c5ca492bb9eadbf9aae18561530f65a10 100644 --- a/src/gs-hardware-support-context-dialog.c +++ b/src/gs-hardware-support-context-dialog.c @@ -40,6 +40,7 @@ #include "gs-common.h" #include "gs-context-dialog-row.h" #include "gs-hardware-support-context-dialog.h" +#include "gs-lozenge.h" struct _GsHardwareSupportContextDialog { @@ -49,7 +50,6 @@ struct _GsHardwareSupportContextDialog gulong app_notify_handler_relations; gulong app_notify_handler_name; - GtkImage *icon; GtkWidget *lozenge; GtkLabel *title; GtkListBox *relations_list; @@ -722,7 +722,7 @@ update_relations_list (GsHardwareSupportContextDialog *self) g_assert_not_reached (); } - gtk_image_set_from_icon_name (GTK_IMAGE (self->icon), icon_name); + gs_lozenge_set_icon_name (GS_LOZENGE (self->lozenge), icon_name); gtk_label_set_text (self->title, title); context = gtk_widget_get_style_context (self->lozenge); @@ -826,7 +826,6 @@ gs_hardware_support_context_dialog_class_init (GsHardwareSupportContextDialogCla gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-hardware-support-context-dialog.ui"); - gtk_widget_class_bind_template_child (widget_class, GsHardwareSupportContextDialog, icon); gtk_widget_class_bind_template_child (widget_class, GsHardwareSupportContextDialog, lozenge); gtk_widget_class_bind_template_child (widget_class, GsHardwareSupportContextDialog, title); gtk_widget_class_bind_template_child (widget_class, GsHardwareSupportContextDialog, relations_list); diff --git a/src/gs-hardware-support-context-dialog.ui b/src/gs-hardware-support-context-dialog.ui index 65fa0ee4d4b257e0f9e542ac5f072d2ff369dbd8..5ce7a72b0d43b4a4af92960bab2107417e84c9c8 100644 --- a/src/gs-hardware-support-context-dialog.ui +++ b/src/gs-hardware-support-context-dialog.ui @@ -23,25 +23,18 @@ 12 - - center + + False + + safety-symbolic + 24 - - - center - True - - safety-symbolic - 24 - - title - - - + + title + diff --git a/src/gs-layout-manager.c b/src/gs-layout-manager.c new file mode 100644 index 0000000000000000000000000000000000000000..37fcf49855039fe52e8c88a9285dd3f115e39ba4 --- /dev/null +++ b/src/gs-layout-manager.c @@ -0,0 +1,110 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2021 Endless OS Foundation LLC + * + * Author: Georges Basile Stavracas Neto + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include "gs-layout-manager.h" + +/* + * The GsLayoutManager is a copy of the GtkBoxLayout, only + * declared as a derivable class, to avoid code duplication. + */ + +G_DEFINE_TYPE (GsLayoutManager, gs_layout_manager, GTK_TYPE_LAYOUT_MANAGER) + +static void +gs_layout_manager_measure (GtkLayoutManager *layout_manager, + GtkWidget *widget, + GtkOrientation orientation, + gint for_size, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) +{ + GtkWidget *child; + gint min = 0; + gint nat = 0; + + for (child = gtk_widget_get_first_child (widget); + child != NULL; + child = gtk_widget_get_next_sibling (child)) { + gint child_min_baseline = -1; + gint child_nat_baseline = -1; + gint child_min = 0; + gint child_nat = 0; + + if (!gtk_widget_should_layout (child)) + continue; + + gtk_widget_measure (child, orientation, + for_size, + &child_min, &child_nat, + &child_min_baseline, + &child_nat_baseline); + + min = MAX (min, child_min); + nat = MAX (nat, 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); + } + + *minimum = min; + *natural = nat; +} + +static void +gs_layout_manager_allocate (GtkLayoutManager *layout_manager, + GtkWidget *widget, + gint width, + gint height, + gint baseline) +{ + GtkWidget *child; + + for (child = gtk_widget_get_first_child (widget); + child != NULL; + child = gtk_widget_get_next_sibling (child)) { + if (child && gtk_widget_should_layout (child)) + gtk_widget_allocate (child, width, height, baseline, NULL); + } +} + +static void +gs_layout_manager_class_init (GsLayoutManagerClass *klass) +{ + GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); + + layout_manager_class->measure = gs_layout_manager_measure; + layout_manager_class->allocate = gs_layout_manager_allocate; +} + +static void +gs_layout_manager_init (GsLayoutManager *self) +{ +} + +/** + * gs_layout_manager_new: + * + * Create a new #GsLayoutManager. + * + * Returns: (transfer full): a new #GsLayoutManager + * + * Since: 43 + **/ +GtkLayoutManager * +gs_layout_manager_new (void) +{ + return g_object_new (GS_TYPE_LAYOUT_MANAGER, NULL); +} diff --git a/src/gs-summary-tile-layout.h b/src/gs-layout-manager.h similarity index 56% rename from src/gs-summary-tile-layout.h rename to src/gs-layout-manager.h index 55d3c1be2b56660f01d45ad20f01d84384105166..bbb661ff479158368c97b4fb8687c37d1796c24c 100644 --- a/src/gs-summary-tile-layout.h +++ b/src/gs-layout-manager.h @@ -16,10 +16,14 @@ G_BEGIN_DECLS -#define GS_TYPE_SUMMARY_TILE_LAYOUT (gs_summary_tile_layout_get_type ()) -G_DECLARE_FINAL_TYPE (GsSummaryTileLayout, gs_summary_tile_layout, GS, SUMMARY_TILE_LAYOUT, GtkLayoutManager) +#define GS_TYPE_LAYOUT_MANAGER (gs_layout_manager_get_type ()) +G_DECLARE_DERIVABLE_TYPE (GsLayoutManager, gs_layout_manager, GS, LAYOUT_MANAGER, GtkLayoutManager) -void gs_summary_tile_layout_set_preferred_width (GsSummaryTileLayout *self, - gint preferred_width); +struct _GsLayoutManagerClass { + GtkLayoutManagerClass parent_class; +}; + +GtkLayoutManager * + gs_layout_manager_new (void); G_END_DECLS diff --git a/src/gs-license-tile.c b/src/gs-license-tile.c index a5fb8e9942d309b03342edc513c8a0fb49f90c74..a68326573be131e23d2158a733d5262028cb4773 100644 --- a/src/gs-license-tile.c +++ b/src/gs-license-tile.c @@ -30,6 +30,7 @@ #include "gs-common.h" #include "gs-license-tile.h" +#include "gs-lozenge.h" struct _GsLicenseTile { @@ -40,7 +41,6 @@ struct _GsLicenseTile gulong notify_urls_handler; GtkWidget *lozenges[3]; - GtkImage *lozenge_images[3]; GtkLabel *title_label; GtkLabel *description_label; GtkListBoxRow *get_involved_row; @@ -125,11 +125,9 @@ gs_license_tile_refresh (GsLicenseTile *self) gtk_style_context_remove_class (context, "green"); gtk_style_context_remove_class (context, "grey"); gtk_style_context_add_class (context, css_class); + gs_lozenge_set_icon_name (GS_LOZENGE (self->lozenges[i]), lozenge_icon_names[i]); } - for (gsize i = 0; i < G_N_ELEMENTS (self->lozenge_images); i++) - gtk_image_set_from_icon_name (self->lozenge_images[i], lozenge_icon_names[i]); - gtk_label_set_label (self->title_label, title); gtk_label_set_label (self->description_label, description); gtk_widget_set_visible (GTK_WIDGET (self->get_involved_row), get_involved_visible); @@ -236,11 +234,8 @@ gs_license_tile_class_init (GsLicenseTileClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-license-tile.ui"); gtk_widget_class_bind_template_child_full (widget_class, "lozenge0", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenges[0])); - gtk_widget_class_bind_template_child_full (widget_class, "lozenge0_image", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenge_images[0])); gtk_widget_class_bind_template_child_full (widget_class, "lozenge1", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenges[1])); - gtk_widget_class_bind_template_child_full (widget_class, "lozenge1_image", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenge_images[1])); gtk_widget_class_bind_template_child_full (widget_class, "lozenge2", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenges[2])); - gtk_widget_class_bind_template_child_full (widget_class, "lozenge2_image", FALSE, G_STRUCT_OFFSET (GsLicenseTile, lozenge_images[2])); gtk_widget_class_bind_template_child (widget_class, GsLicenseTile, title_label); gtk_widget_class_bind_template_child (widget_class, GsLicenseTile, description_label); gtk_widget_class_bind_template_child (widget_class, GsLicenseTile, get_involved_row); diff --git a/src/gs-license-tile.ui b/src/gs-license-tile.ui index ec8a43c9c102f6a113ba68f656e7086362ca5aaf..3ef3075d47c0ce5f63a6ad59e8e121d7dd172d94 100644 --- a/src/gs-license-tile.ui +++ b/src/gs-license-tile.ui @@ -31,51 +31,30 @@ 8 - - center + + True + heart-filled-symbolic - - - center - True - heart-filled-symbolic - - - - center + + True + community-symbolic - - - center - True - community-symbolic - - - - center + + True + sign-language-symbolic - - - center - True - sign-language-symbolic - - diff --git a/src/gs-lozenge-layout.c b/src/gs-lozenge-layout.c new file mode 100644 index 0000000000000000000000000000000000000000..037f71aef57075bc2a04f850288884d0dfb2cf34 --- /dev/null +++ b/src/gs-lozenge-layout.c @@ -0,0 +1,179 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat (www.redhat.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include "gs-lozenge-layout.h" + +struct _GsLozengeLayout +{ + GsLayoutManager parent_instance; + + gboolean circular; +}; + +G_DEFINE_TYPE (GsLozengeLayout, gs_lozenge_layout, GS_TYPE_LAYOUT_MANAGER) + +typedef enum { + PROP_CIRCULAR = 1, +} GsLozengeLayoutProperty; + +static GParamSpec *obj_props[PROP_CIRCULAR + 1] = { NULL, }; + +static void +gs_lozenge_layout_measure (GtkLayoutManager *layout_manager, + GtkWidget *widget, + GtkOrientation orientation, + gint for_size, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) +{ + GsLozengeLayout *self = GS_LOZENGE_LAYOUT (layout_manager); + + GTK_LAYOUT_MANAGER_CLASS (gs_lozenge_layout_parent_class)->measure (layout_manager, + widget, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); + + if (self->circular) { + *minimum = MAX (for_size, *minimum); + *natural = *minimum; + *natural_baseline = *minimum_baseline; + } + + if (*natural_baseline > *natural) + *natural_baseline = *natural; + if (*minimum_baseline > *minimum) + *minimum_baseline = *minimum; +} + +static void +gs_lozenge_layout_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsLozengeLayout *self = GS_LOZENGE_LAYOUT (object); + + switch ((GsLozengeLayoutProperty) prop_id) { + case PROP_CIRCULAR: + g_value_set_boolean (value, gs_lozenge_layout_get_circular (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_lozenge_layout_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsLozengeLayout *self = GS_LOZENGE_LAYOUT (object); + + switch ((GsLozengeLayoutProperty) prop_id) { + case PROP_CIRCULAR: + gs_lozenge_layout_set_circular (self, g_value_get_boolean (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_lozenge_layout_class_init (GsLozengeLayoutClass *klass) +{ + GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); + GObjectClass *object_class = G_OBJECT_CLASS (klass); + + layout_manager_class->measure = gs_lozenge_layout_measure; + + object_class->get_property = gs_lozenge_layout_get_property; + object_class->set_property = gs_lozenge_layout_set_property; + + /** + * GsLozengeLayout:circular: + * + * Whether the lozenge should be circular, thus its size square. + * + * The default is %FALSE. + * + * Since: 43 + */ + obj_props[PROP_CIRCULAR] = + g_param_spec_boolean ("circular", NULL, NULL, + FALSE, + 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); +} + +static void +gs_lozenge_layout_init (GsLozengeLayout *self) +{ +} + +/** + * gs_lozenge_layout_new: + * + * Create a new #GsLozengeLayout. + * + * Returns: (transfer full): a new #GsLozengeLayout + * + * Since: 43 + **/ +GsLozengeLayout * +gs_lozenge_layout_new (void) +{ + return g_object_new (GS_TYPE_LOZENGE_LAYOUT, NULL); +} + +/** + * gs_lozenge_layout_get_circular: + * @self: a #GsLozengeLayout + * + * Get the value of #GsLozengeLayout:circular. + * + * Returns: %TRUE if the lozenge has to be circular, %FALSE otherwise + * Since: 43 + */ +gboolean +gs_lozenge_layout_get_circular (GsLozengeLayout *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE_LAYOUT (self), FALSE); + + return self->circular; +} + +/** + * gs_lozenge_layout_set_circular: + * @self: a #GsLozengeLayout + * @value: %TRUE if the lozenge should be circular, %FALSE otherwise + * + * Set the value of #GsLozengeLayout:circular to @value. + * + * Since: 43 + */ +void +gs_lozenge_layout_set_circular (GsLozengeLayout *self, + gboolean value) +{ + g_return_if_fail (GS_IS_LOZENGE_LAYOUT (self)); + + if ((!self->circular) == (!value)) + return; + + self->circular = value; + + gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self)); + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CIRCULAR]); +} diff --git a/src/gs-lozenge-layout.h b/src/gs-lozenge-layout.h new file mode 100644 index 0000000000000000000000000000000000000000..e731819bdd26e738d6c14c58143096b560a30d6f --- /dev/null +++ b/src/gs-lozenge-layout.h @@ -0,0 +1,28 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat (www.redhat.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#pragma once + +#include +#include +#include + +#include "gs-layout-manager.h" + +G_BEGIN_DECLS + +#define GS_TYPE_LOZENGE_LAYOUT (gs_lozenge_layout_get_type ()) +G_DECLARE_FINAL_TYPE (GsLozengeLayout, gs_lozenge_layout, GS, LOZENGE_LAYOUT, GsLayoutManager) + +GsLozengeLayout * + gs_lozenge_layout_new (void); +gboolean gs_lozenge_layout_get_circular (GsLozengeLayout *self); +void gs_lozenge_layout_set_circular (GsLozengeLayout *self, + gboolean value); + +G_END_DECLS diff --git a/src/gs-lozenge.c b/src/gs-lozenge.c new file mode 100644 index 0000000000000000000000000000000000000000..39886cf73381c56a49cf5c5ed6ed48bc1820ce93 --- /dev/null +++ b/src/gs-lozenge.c @@ -0,0 +1,415 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat (www.redhat.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include "config.h" + +#include "gs-lozenge.h" +#include "gs-lozenge-layout.h" + +struct _GsLozenge +{ + GtkBox parent_instance; + + GtkWidget *image; /* (unowned) */ + GtkWidget *label; /* (unowned) */ + + gchar *icon_name; + gchar *text; + gchar *markup; + gboolean circular; + gint pixel_size; +}; + +G_DEFINE_TYPE (GsLozenge, gs_lozenge, GTK_TYPE_BOX) + +typedef enum { + PROP_CIRCULAR = 1, + PROP_ICON_NAME, + PROP_PIXEL_SIZE, + PROP_TEXT, + PROP_MARKUP +} GsLozengeProperty; + +static GParamSpec *obj_props[PROP_MARKUP + 1] = { NULL, }; + +static void +gs_lozenge_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GsLozenge *self = GS_LOZENGE (object); + + switch ((GsLozengeProperty) prop_id) { + case PROP_CIRCULAR: + g_value_set_boolean (value, gs_lozenge_get_circular (self)); + break; + case PROP_ICON_NAME: + g_value_set_string (value, gs_lozenge_get_icon_name (self)); + break; + case PROP_PIXEL_SIZE: + g_value_set_int (value, gs_lozenge_get_pixel_size (self)); + break; + case PROP_TEXT: + g_value_set_string (value, gs_lozenge_get_text (self)); + break; + case PROP_MARKUP: + g_value_set_string (value, gs_lozenge_get_markup (self)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_lozenge_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GsLozenge *self = GS_LOZENGE (object); + + switch ((GsLozengeProperty) prop_id) { + case PROP_CIRCULAR: + gs_lozenge_set_circular (self, g_value_get_boolean (value)); + break; + case PROP_ICON_NAME: + gs_lozenge_set_icon_name (self, g_value_get_string (value)); + break; + case PROP_PIXEL_SIZE: + gs_lozenge_set_pixel_size (self, g_value_get_int (value)); + break; + case PROP_TEXT: + gs_lozenge_set_text (self, g_value_get_string (value)); + break; + case PROP_MARKUP: + gs_lozenge_set_markup (self, g_value_get_string (value)); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gs_lozenge_dispose (GObject *object) +{ + GsLozenge *self = GS_LOZENGE (object); + + g_clear_pointer (&self->icon_name, g_free); + g_clear_pointer (&self->text, g_free); + g_clear_pointer (&self->markup, g_free); + + G_OBJECT_CLASS (gs_lozenge_parent_class)->dispose (object); +} + +static void +gs_lozenge_class_init (GsLozengeClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS (klass); + GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass); + + object_class->get_property = gs_lozenge_get_property; + object_class->set_property = gs_lozenge_set_property; + object_class->dispose = gs_lozenge_dispose; + + /** + * GsLozenge:circular: + * + * Whether the lozenge should be circular/square widget. + * + * Since: 43 + */ + obj_props[PROP_CIRCULAR] = + g_param_spec_boolean ("circular", NULL, NULL, + FALSE, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GsLozenge:icon-name: + * + * An icon name for the lozenge. Setting this property turns + * the lozenge into the icon mode, which mean showing the icon, + * not the markup. + * + * Since: 43 + */ + obj_props[PROP_ICON_NAME] = + g_param_spec_string ("icon-name", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GsLozenge:pixel-size: + * + * An icon pixel size for the lozenge. + * + * Since: 43 + */ + obj_props[PROP_PIXEL_SIZE] = + g_param_spec_int ("pixel-size", NULL, NULL, + 0, G_MAXINT, 16, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GsLozenge:text: + * + * A plain text for the lozenge. Setting this property turns + * the lozenge into the text mode, which mean showing the text, + * not the icon. + * + * Since: 43 + */ + obj_props[PROP_TEXT] = + g_param_spec_string ("text", NULL, NULL, + NULL, + G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS); + + /** + * GsLozenge:markup: + * + * A markup text for the lozenge. Setting this property turns + * the lozenge into the text mode, which mean showing the markup, + * not the icon. + * + * Since: 43 + */ + obj_props[PROP_MARKUP] = + g_param_spec_string ("markup", NULL, NULL, + NULL, + 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); + + gtk_widget_class_set_layout_manager_type (widget_class, GS_TYPE_LOZENGE_LAYOUT); + gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-lozenge.ui"); + + gtk_widget_class_bind_template_child (widget_class, GsLozenge, image); + gtk_widget_class_bind_template_child (widget_class, GsLozenge, label); +} + +static void +gs_lozenge_init (GsLozenge *self) +{ + gtk_widget_init_template (GTK_WIDGET (self)); + + self->pixel_size = 16; +} + +/** + * gs_lozenge_new: + * + * Returns: (transfer full): a new #GsLozenge + * + * Since: 43 + **/ +GtkWidget * +gs_lozenge_new (void) +{ + return g_object_new (GS_TYPE_LOZENGE, NULL); +} + +const gchar * +gs_lozenge_get_icon_name (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), NULL); + + return self->icon_name; +} + +gboolean +gs_lozenge_get_circular (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), FALSE); + + return self->circular; +} + +void +gs_lozenge_set_circular (GsLozenge *self, + gboolean value) +{ + GtkLayoutManager *layout_manager; + + g_return_if_fail (GS_IS_LOZENGE (self)); + + if ((!self->circular) == (!value)) + return; + + self->circular = value; + + layout_manager = gtk_widget_get_layout_manager (GTK_WIDGET (self)); + gs_lozenge_layout_set_circular (GS_LOZENGE_LAYOUT (layout_manager), self->circular); + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_CIRCULAR]); +} + +void +gs_lozenge_set_icon_name (GsLozenge *self, + const gchar *value) +{ + g_return_if_fail (GS_IS_LOZENGE (self)); + + if (value != NULL && *value == '\0') + value = NULL; + + if (g_strcmp0 (self->icon_name, value) == 0) + return; + + g_clear_pointer (&self->icon_name, g_free); + self->icon_name = g_strdup (value); + + if (self->icon_name == NULL) { + gtk_widget_hide (self->image); + gtk_widget_show (self->label); + } else { + gtk_image_set_from_icon_name (GTK_IMAGE (self->image), self->icon_name); + gtk_widget_hide (self->label); + gtk_widget_show (self->image); + } + + /* Clean up the other properties before notifying of the changed property name */ + + if (self->text != NULL) { + g_clear_pointer (&self->text, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]); + } + + if (self->markup != NULL) { + g_clear_pointer (&self->markup, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MARKUP]); + } + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ICON_NAME]); +} + +gint +gs_lozenge_get_pixel_size (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), 0); + + return self->pixel_size; +} + +void +gs_lozenge_set_pixel_size (GsLozenge *self, + gint value) +{ + g_return_if_fail (GS_IS_LOZENGE (self)); + + if (self->pixel_size == value) + return; + + self->pixel_size = value; + + gtk_image_set_pixel_size (GTK_IMAGE (self->image), self->pixel_size); + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_PIXEL_SIZE]); +} + +gboolean +gs_lozenge_get_use_markup (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), FALSE); + return gtk_label_get_use_markup (GTK_LABEL (self->label)); +} + +const gchar * +gs_lozenge_get_text (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), NULL); + + return self->text; +} + +void +gs_lozenge_set_text (GsLozenge *self, + const gchar *value) +{ + g_return_if_fail (GS_IS_LOZENGE (self)); + + if (value != NULL && *value == '\0') + value = NULL; + + if (g_strcmp0 (self->text, value) == 0) + return; + + g_clear_pointer (&self->text, g_free); + self->text = g_strdup (value); + + if (self->text == NULL) { + gtk_widget_hide (self->label); + gtk_widget_show (self->image); + } else { + gtk_label_set_text (GTK_LABEL (self->label), self->text); + gtk_widget_hide (self->image); + gtk_widget_show (self->label); + } + + /* Clean up the other properties before notifying of the changed property name */ + + if (self->icon_name != NULL) { + g_clear_pointer (&self->icon_name, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ICON_NAME]); + } + + if (self->markup != NULL) { + g_clear_pointer (&self->markup, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MARKUP]); + } + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]); +} + +const gchar * +gs_lozenge_get_markup (GsLozenge *self) +{ + g_return_val_if_fail (GS_IS_LOZENGE (self), NULL); + + return self->markup; +} + +void +gs_lozenge_set_markup (GsLozenge *self, + const gchar *value) +{ + g_return_if_fail (GS_IS_LOZENGE (self)); + + if (value != NULL && *value == '\0') + value = NULL; + + if (g_strcmp0 (self->markup, value) == 0) + return; + + g_clear_pointer (&self->markup, g_free); + self->markup = g_strdup (value); + + if (self->markup == NULL) { + gtk_widget_hide (self->label); + gtk_widget_show (self->image); + } else { + gtk_label_set_markup (GTK_LABEL (self->label), self->markup); + gtk_widget_hide (self->image); + gtk_widget_show (self->label); + } + + /* Clean up the other properties before notifying of the changed property name */ + + if (self->icon_name != NULL) { + g_clear_pointer (&self->icon_name, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_ICON_NAME]); + } + + if (self->text != NULL) { + g_clear_pointer (&self->text, g_free); + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_TEXT]); + } + + g_object_notify_by_pspec (G_OBJECT (self), obj_props[PROP_MARKUP]); +} diff --git a/src/gs-lozenge.h b/src/gs-lozenge.h new file mode 100644 index 0000000000000000000000000000000000000000..d3319767267df318b55440d2e64f41ef006069a8 --- /dev/null +++ b/src/gs-lozenge.h @@ -0,0 +1,38 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- + * vi:set noexpandtab tabstop=8 shiftwidth=8: + * + * Copyright (C) 2022 Red Hat (www.redhat.com) + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#pragma once + +#include +#include +#include + +G_BEGIN_DECLS + +#define GS_TYPE_LOZENGE (gs_lozenge_get_type ()) +G_DECLARE_FINAL_TYPE (GsLozenge, gs_lozenge, GS, LOZENGE, GtkBox) + +GtkWidget * gs_lozenge_new (void); +gboolean gs_lozenge_get_circular (GsLozenge *self); +void gs_lozenge_set_circular (GsLozenge *self, + gboolean value); +const gchar * gs_lozenge_get_icon_name (GsLozenge *self); +void gs_lozenge_set_icon_name (GsLozenge *self, + const gchar *value); +gint gs_lozenge_get_pixel_size (GsLozenge *self); +void gs_lozenge_set_pixel_size (GsLozenge *self, + gint value); +gboolean gs_lozenge_get_use_markup (GsLozenge *self); +const gchar * gs_lozenge_get_text (GsLozenge *self); +void gs_lozenge_set_text (GsLozenge *self, + const gchar *value); +const gchar * gs_lozenge_get_markup (GsLozenge *self); +void gs_lozenge_set_markup (GsLozenge *self, + const gchar *value); + +G_END_DECLS diff --git a/src/gs-lozenge.ui b/src/gs-lozenge.ui new file mode 100644 index 0000000000000000000000000000000000000000..545d803f407ddc73f2f5999ece66b17b0b609a79 --- /dev/null +++ b/src/gs-lozenge.ui @@ -0,0 +1,33 @@ + + + + + diff --git a/src/gs-safety-context-dialog.c b/src/gs-safety-context-dialog.c index 1cb955f1c5a76212ac77f36974fea7de432bb3a5..a05a3543b736154a5d340d9ba2189a38fa9d2f06 100644 --- a/src/gs-safety-context-dialog.c +++ b/src/gs-safety-context-dialog.c @@ -38,6 +38,7 @@ #include "gs-app.h" #include "gs-common.h" #include "gs-context-dialog-row.h" +#include "gs-lozenge.h" #include "gs-safety-context-dialog.h" struct _GsSafetyContextDialog @@ -51,7 +52,6 @@ struct _GsSafetyContextDialog gulong app_notify_handler_license; gulong app_notify_handler_related; - GtkImage *icon; GtkWidget *lozenge; GtkLabel *title; GtkListBox *permissions_list; @@ -374,7 +374,7 @@ update_permissions_list (GsSafetyContextDialog *self) g_assert_not_reached (); } - gtk_image_set_from_icon_name (GTK_IMAGE (self->icon), icon_name); + gs_lozenge_set_icon_name (GS_LOZENGE (self->lozenge), icon_name); gtk_label_set_text (self->title, title); context = gtk_widget_get_style_context (self->lozenge); @@ -533,7 +533,6 @@ gs_safety_context_dialog_class_init (GsSafetyContextDialogClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-safety-context-dialog.ui"); - gtk_widget_class_bind_template_child (widget_class, GsSafetyContextDialog, icon); gtk_widget_class_bind_template_child (widget_class, GsSafetyContextDialog, lozenge); gtk_widget_class_bind_template_child (widget_class, GsSafetyContextDialog, title); gtk_widget_class_bind_template_child (widget_class, GsSafetyContextDialog, permissions_list); diff --git a/src/gs-safety-context-dialog.ui b/src/gs-safety-context-dialog.ui index 6d35151c146953dbd7544aa638ca8839cf3f0d67..836a7c49db1ba277395e22ed173121c116387817 100644 --- a/src/gs-safety-context-dialog.ui +++ b/src/gs-safety-context-dialog.ui @@ -23,25 +23,18 @@ 12 - - center + + True + + safety-symbolic + 24 - - - center - True - - safety-symbolic - 24 - - title - - - + + title + diff --git a/src/gs-storage-context-dialog.c b/src/gs-storage-context-dialog.c index 7ca2e29d9d8976274fd32297af9747d72fdce1b9..e0ca3778999d8f01f8d8a384aeffb4853873905f 100644 --- a/src/gs-storage-context-dialog.c +++ b/src/gs-storage-context-dialog.c @@ -38,6 +38,7 @@ #include "gs-app.h" #include "gs-common.h" #include "gs-context-dialog-row.h" +#include "gs-lozenge.h" #include "gs-storage-context-dialog.h" struct _GsStorageContextDialog @@ -48,7 +49,6 @@ struct _GsStorageContextDialog gulong app_notify_handler; GtkSizeGroup *lozenge_size_group; - GtkLabel *lozenge_content; GtkWidget *lozenge; GtkLabel *title; GtkListBox *sizes_list; @@ -98,7 +98,8 @@ add_size_row (GtkListBox *list_box, row = gs_context_dialog_row_new_text (size_bytes_str, GS_CONTEXT_DIALOG_ROW_IMPORTANCE_NEUTRAL, title, description); - gs_context_dialog_row_set_content_is_markup (GS_CONTEXT_DIALOG_ROW (row), is_markup); + if (is_markup) + gs_context_dialog_row_set_content_markup (GS_CONTEXT_DIALOG_ROW (row), size_bytes_str); gs_context_dialog_row_set_size_groups (GS_CONTEXT_DIALOG_ROW (row), lozenge_size_group, NULL, NULL); gtk_list_box_append (list_box, GTK_WIDGET (row)); } @@ -187,9 +188,9 @@ update_sizes_list (GsStorageContextDialog *self) title_size_bytes_str = g_strdup (C_("Download size", "Unknown")); if (is_markup) - gtk_label_set_markup (self->lozenge_content, title_size_bytes_str); + gs_lozenge_set_markup (GS_LOZENGE (self->lozenge), title_size_bytes_str); else - gtk_label_set_text (self->lozenge_content, title_size_bytes_str); + gs_lozenge_set_text (GS_LOZENGE (self->lozenge), title_size_bytes_str); gtk_label_set_text (self->title, title); @@ -332,7 +333,6 @@ gs_storage_context_dialog_class_init (GsStorageContextDialogClass *klass) gtk_widget_class_set_template_from_resource (widget_class, "/org/gnome/Software/gs-storage-context-dialog.ui"); gtk_widget_class_bind_template_child (widget_class, GsStorageContextDialog, lozenge_size_group); - gtk_widget_class_bind_template_child (widget_class, GsStorageContextDialog, lozenge_content); gtk_widget_class_bind_template_child (widget_class, GsStorageContextDialog, lozenge); gtk_widget_class_bind_template_child (widget_class, GsStorageContextDialog, title); gtk_widget_class_bind_template_child (widget_class, GsStorageContextDialog, sizes_list); diff --git a/src/gs-storage-context-dialog.ui b/src/gs-storage-context-dialog.ui index 4b3de96c02e7f9a3b714ba67b367b829504e0511..de2f589c84dc5b4fd18af244a39cbe3ebf3cfad0 100644 --- a/src/gs-storage-context-dialog.ui +++ b/src/gs-storage-context-dialog.ui @@ -23,25 +23,15 @@ 12 - - center + + False - - - center - True - - 20 MB - 0.5 - - title - - - + + title + diff --git a/src/gs-summary-tile-layout.c b/src/gs-summary-tile-layout.c deleted file mode 100644 index 5e738f16cc3127917ff859fb7d36da10fcc10209..0000000000000000000000000000000000000000 --- a/src/gs-summary-tile-layout.c +++ /dev/null @@ -1,114 +0,0 @@ -/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- - * vi:set noexpandtab tabstop=8 shiftwidth=8: - * - * Copyright (C) 2021 Endless OS Foundation LLC - * - * Author: Georges Basile Stavracas Neto - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include "gs-summary-tile-layout.h" - -struct _GsSummaryTileLayout -{ - GtkLayoutManager parent_instance; - - gint preferred_width; -}; - -G_DEFINE_TYPE (GsSummaryTileLayout, gs_summary_tile_layout, GTK_TYPE_LAYOUT_MANAGER) - -static void -gs_summary_tile_layout_layout_measure (GtkLayoutManager *layout_manager, - GtkWidget *widget, - GtkOrientation orientation, - gint for_size, - gint *minimum, - gint *natural, - gint *minimum_baseline, - gint *natural_baseline) -{ - GsSummaryTileLayout *self = GS_SUMMARY_TILE_LAYOUT (layout_manager); - GtkWidget *child; - gint min = 0; - gint nat = 0; - - for (child = gtk_widget_get_first_child (widget); - child != NULL; - child = gtk_widget_get_next_sibling (child)) { - gint child_min_baseline = -1; - gint child_nat_baseline = -1; - gint child_min = 0; - gint child_nat = 0; - - if (!gtk_widget_should_layout (child)) - continue; - - gtk_widget_measure (child, orientation, - for_size, - &child_min, &child_nat, - &child_min_baseline, - &child_nat_baseline); - - min = MAX (min, child_min); - nat = MAX (nat, 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); - } - - *minimum = min; - *natural = nat; - - /* Limit the natural width */ - if (self->preferred_width > 0 && orientation == GTK_ORIENTATION_HORIZONTAL) - *natural = MAX (min, self->preferred_width); -} - -static void -gs_summary_tile_layout_layout_allocate (GtkLayoutManager *layout_manager, - GtkWidget *widget, - gint width, - gint height, - gint baseline) -{ - GtkWidget *child; - - for (child = gtk_widget_get_first_child (widget); - child != NULL; - child = gtk_widget_get_next_sibling (child)) { - if (child && gtk_widget_should_layout (child)) - gtk_widget_allocate (child, width, height, baseline, NULL); - } -} - -static void -gs_summary_tile_layout_class_init (GsSummaryTileLayoutClass *klass) -{ - GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); - - layout_manager_class->measure = gs_summary_tile_layout_layout_measure; - layout_manager_class->allocate = gs_summary_tile_layout_layout_allocate; -} - -static void -gs_summary_tile_layout_init (GsSummaryTileLayout *self) -{ - self->preferred_width = -1; -} - -void -gs_summary_tile_layout_set_preferred_width (GsSummaryTileLayout *self, - gint preferred_width) -{ - g_return_if_fail (GS_IS_SUMMARY_TILE_LAYOUT (self)); - - if (self->preferred_width == preferred_width) - return; - - self->preferred_width = preferred_width; - gtk_layout_manager_layout_changed (GTK_LAYOUT_MANAGER (self)); -} diff --git a/src/gs-summary-tile.c b/src/gs-summary-tile.c index c447eb617ee7267342790dbc8fe4cf7ab98c23ef..dcd977b4456f43bc7d2c88ec03f22bab159d79a2 100644 --- a/src/gs-summary-tile.c +++ b/src/gs-summary-tile.c @@ -12,9 +12,55 @@ #include #include "gs-summary-tile.h" -#include "gs-summary-tile-layout.h" +#include "gs-layout-manager.h" #include "gs-common.h" +#define GS_TYPE_SUMMARY_TILE_LAYOUT (gs_summary_tile_layout_get_type ()) +G_DECLARE_FINAL_TYPE (GsSummaryTileLayout, gs_summary_tile_layout, GS, SUMMARY_TILE_LAYOUT, GsLayoutManager) + +struct _GsSummaryTileLayout +{ + GsLayoutManager parent_instance; + + gint preferred_width; +}; + +G_DEFINE_TYPE (GsSummaryTileLayout, gs_summary_tile_layout, GS_TYPE_LAYOUT_MANAGER) + +static void +gs_summary_tile_layout_measure (GtkLayoutManager *layout_manager, + GtkWidget *widget, + GtkOrientation orientation, + gint for_size, + gint *minimum, + gint *natural, + gint *minimum_baseline, + gint *natural_baseline) +{ + GsSummaryTileLayout *self = GS_SUMMARY_TILE_LAYOUT (layout_manager); + + GTK_LAYOUT_MANAGER_CLASS (gs_summary_tile_layout_parent_class)->measure (layout_manager, + widget, orientation, for_size, minimum, natural, minimum_baseline, natural_baseline); + + /* Limit the natural width */ + if (self->preferred_width > 0 && orientation == GTK_ORIENTATION_HORIZONTAL) + *natural = MAX (*minimum, self->preferred_width); +} + +static void +gs_summary_tile_layout_class_init (GsSummaryTileLayoutClass *klass) +{ + GtkLayoutManagerClass *layout_manager_class = GTK_LAYOUT_MANAGER_CLASS (klass); + layout_manager_class->measure = gs_summary_tile_layout_measure; +} + +static void +gs_summary_tile_layout_init (GsSummaryTileLayout *self) +{ +} + +/* ********************************************************************* */ + struct _GsSummaryTile { GsAppTile parent_instance; @@ -138,8 +184,8 @@ gs_summary_tile_set_property (GObject *object, case PROP_PREFERRED_WIDTH: app_tile->preferred_width = g_value_get_int (value); layout_manager = gtk_widget_get_layout_manager (GTK_WIDGET (app_tile)); - gs_summary_tile_layout_set_preferred_width (GS_SUMMARY_TILE_LAYOUT (layout_manager), - g_value_get_int (value)); + GS_SUMMARY_TILE_LAYOUT (layout_manager)->preferred_width = app_tile->preferred_width; + gtk_layout_manager_layout_changed (layout_manager); g_object_notify_by_pspec (object, obj_props[PROP_PREFERRED_WIDTH]); break; default: diff --git a/src/meson.build b/src/meson.build index e1ef51afb812b8aa3ec19a88de394a50bc072ed5..1b58586916f1eaa7a1b1a53b81f015f3a5920533 100644 --- a/src/meson.build +++ b/src/meson.build @@ -50,8 +50,11 @@ gnome_software_sources = [ 'gs-info-window.c', 'gs-installed-page.c', 'gs-language.c', + 'gs-layout-manager.c', 'gs-license-tile.c', 'gs-loading-page.c', + 'gs-lozenge.c', + 'gs-lozenge-layout.c', 'gs-main.c', 'gs-metered-data-dialog.c', 'gs-moderate-page.c', @@ -79,7 +82,6 @@ gnome_software_sources = [ 'gs-star-widget.c', 'gs-storage-context-dialog.c', 'gs-summary-tile.c', - 'gs-summary-tile-layout.c', 'gs-update-dialog.c', 'gs-update-list.c', 'gs-update-monitor.c',