[recipes] Change strategy for tile backgrounds
- From: Matthias Clasen <matthiasc src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [recipes] Change strategy for tile backgrounds
- Date: Mon, 2 Jan 2017 15:28:39 +0000 (UTC)
commit d01a69c1b058597cd89c99e170e1002ae335ab14
Author: Matthias Clasen <mclasen redhat com>
Date: Mon Jan 2 10:19:17 2017 -0500
Change strategy for tile backgrounds
Instead of creating a custom per-widget style provider
that needs to load the image again, generate just a single
style provider that provides the style for all recipes
and another one for all the chefs. This avoids lots of
image reloading and speeds up the list pages quite a bit.
src/gr-chef-tile.c | 88 +++++++++++++++++++++++++++---------
src/gr-chef-tile.h | 3 +
src/gr-list-page.c | 44 +++++--------------
src/gr-recipe-tile.c | 119 +++++++++++++++++++++++++++++++++++++-----------
src/gr-recipe-tile.h | 2 +
src/gr-recipe-tile.ui | 2 +
src/gr-recipes-page.c | 6 +++
7 files changed, 182 insertions(+), 82 deletions(-)
---
diff --git a/src/gr-chef-tile.c b/src/gr-chef-tile.c
index 3473e9c..5160608 100644
--- a/src/gr-chef-tile.c
+++ b/src/gr-chef-tile.c
@@ -73,45 +73,91 @@ gr_chef_tile_class_init (GrChefTileClass *klass)
}
static void
-chef_tile_set_chef (GrChefTile *tile,
- GrChef *chef)
+add_chef_css (GrChef *chef,
+ GString *css)
{
- const char *name;
+ const char *id;
const char *image_path;
- GtkStyleContext *context;
- g_autofree char *css = NULL;
- g_autoptr(GtkCssProvider) provider = NULL;
- g_set_object (&tile->chef, chef);
-
- name = gr_chef_get_name (chef);
+ id = gr_chef_get_id (chef);
image_path = gr_chef_get_image (chef);
- gtk_label_set_label (GTK_LABEL (tile->label), name);
-
if (image_path != NULL && image_path[0] != '\0')
- css = g_strdup_printf ("image.chef {\n"
+ g_string_append_printf (css,
+ "image.chef.%s {\n"
" background: url('%s');\n"
" background-size: 64px;\n"
" min-width: 64px;\n"
" min-height: 64px;\n"
- "}", image_path);
+ "}\n\n", id, image_path);
else
- css = g_strdup_printf ("image.chef {\n"
+ g_string_append_printf (css,
+ "image.chef.%s {\n"
" background: rgb(%d,%d,%d);\n"
" min-width: 64px;\n"
" min-height: 64px;\n"
- "}",
+ "}\n\n",
+ id,
g_random_int_range (0, 255),
g_random_int_range (0, 255),
g_random_int_range (0, 255));
+}
+
+static GtkCssProvider *provider = NULL;
+
+void
+gr_chef_tile_recreate_css (void)
+{
+ GrRecipeStore *store;
+ g_autofree char **keys = NULL;
+ guint length;
+ g_autoptr(GString) css = NULL;
+ int i;
+
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+ keys = gr_recipe_store_get_chef_keys (store, &length);
+
+ css = g_string_new ("");
+
+ for (i = 0; i < length; i++) {
+ g_autoptr (GrChef) chef = NULL;
+ chef = gr_recipe_store_get_chef (store, keys[i]);
+ add_chef_css (chef, css);
+ }
+
+ if (provider == NULL) {
+ provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+
+ gtk_css_provider_load_from_data (provider, css->str, css->len, NULL);
+}
+
+static void
+chef_tile_set_chef (GrChefTile *tile,
+ GrChef *chef)
+{
+ if (tile->chef) {
+ const char *elem;
+
+ elem = gr_chef_get_id (tile->chef);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (tile->image), elem);
+ }
+
+ g_set_object (&tile->chef, chef);
+
+ if (tile->chef) {
+ const char *elem;
+ const char *name;
+
+ elem = gr_chef_get_id (tile->chef);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tile->image), elem);
- provider = gtk_css_provider_new ();
- gtk_css_provider_load_from_data (provider, css, -1, NULL);
- context = gtk_widget_get_style_context (tile->image);
- gtk_style_context_add_provider (context,
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ name = gr_chef_get_name (chef);
+ gtk_label_set_label (GTK_LABEL (tile->label), name);
+ }
}
GtkWidget *
diff --git a/src/gr-chef-tile.h b/src/gr-chef-tile.h
index f255a70..b44123f 100644
--- a/src/gr-chef-tile.h
+++ b/src/gr-chef-tile.h
@@ -32,4 +32,7 @@ G_DECLARE_FINAL_TYPE (GrChefTile, gr_chef_tile, GR, CHEF_TILE, GtkBox)
GtkWidget *gr_chef_tile_new (GrChef *chef);
GrChef *gr_chef_tile_get_chef (GrChefTile *tile);
+void gr_chef_tile_recreate_css (void);
+
+
G_END_DECLS
diff --git a/src/gr-list-page.c b/src/gr-list-page.c
index 81386cc..9fdb264 100644
--- a/src/gr-list-page.c
+++ b/src/gr-list-page.c
@@ -32,7 +32,6 @@
#include "gr-season.h"
#include "gr-category-tile.h"
-
struct _GrListPage
{
GtkBox parent_instance;
@@ -66,6 +65,11 @@ static void connect_store_signals (GrListPage *page);
static void
clear_data (GrListPage *self)
{
+ if (self->chef) {
+ gtk_style_context_remove_class (gtk_widget_get_style_context (self->chef_image),
+ gr_chef_get_id (self->chef));
+ }
+
g_clear_object (&self->chef);
self->diet = 0;
self->favorites = FALSE;
@@ -289,17 +293,16 @@ gr_list_page_populate_from_chef (GrListPage *self,
GrRecipeStore *store;
const char *id;
char *tmp;
- const char *image_path;
const char *description;
- GtkStyleContext *context;
- g_autofree char *css = NULL;
- g_autoptr(GtkCssProvider) provider = NULL;
g_autofree char *term = NULL;
g_object_ref (chef);
clear_data (self);
self->chef = chef;
+ gtk_style_context_add_class (gtk_widget_get_style_context (self->chef_image),
+ gr_chef_get_id (self->chef));
+
gtk_widget_show (self->chef_grid);
gtk_widget_show (self->heading);
gtk_widget_hide (self->diet_description);
@@ -308,32 +311,6 @@ gr_list_page_populate_from_chef (GrListPage *self,
description = gr_chef_get_translated_description (chef);
gtk_label_set_markup (GTK_LABEL (self->chef_description), description);
- image_path = gr_chef_get_image (chef);
-
- if (image_path != NULL && image_path[0] != '\0')
- css = g_strdup_printf ("image.chef {\n"
- " background: url('%s');\n"
- " background-size: 64px;\n"
- " min-width: 64px;\n"
- " min-height: 64px;\n"
- "}", image_path);
- else
- css = g_strdup_printf ("image.chef {\n"
- " background: rgb(%d,%d,%d);\n"
- " min-width: 64px;\n"
- " min-height: 64px;\n"
- "}",
- g_random_int_range (0, 255),
- g_random_int_range (0, 255),
- g_random_int_range (0, 255));
-
- provider = gtk_css_provider_new ();
- gtk_css_provider_load_from_data (provider, css, -1, NULL);
- context = gtk_widget_get_style_context (self->chef_image);
- gtk_style_context_add_provider (context,
- GTK_STYLE_PROVIDER (provider),
- GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
-
tmp = g_strdup_printf (_("Recipes by %s"), gr_chef_get_name (chef));
gtk_label_set_label (GTK_LABEL (self->heading), tmp);
g_free (tmp);
@@ -349,11 +326,12 @@ gr_list_page_populate_from_chef (GrListPage *self,
else
gtk_label_set_label (GTK_LABEL (self->empty_subtitle), _("Sorry about this."));
- id = gr_chef_get_id (chef);
-
gr_recipe_search_stop (self->search);
gtk_stack_set_visible_child_name (GTK_STACK (self->list_stack), "list");
+
+ id = gr_chef_get_id (chef);
term = g_strconcat ("by:", id, NULL);
+
gr_recipe_search_set_query (self->search, term);
}
diff --git a/src/gr-recipe-tile.c b/src/gr-recipe-tile.c
index 109f7cc..0c72d3c 100644
--- a/src/gr-recipe-tile.c
+++ b/src/gr-recipe-tile.c
@@ -54,37 +54,32 @@ show_details (GrRecipeTile *tile)
}
static void
-recipe_tile_set_recipe (GrRecipeTile *tile,
- GrRecipe *recipe)
+add_recipe_css (GrRecipe *recipe,
+ GString *css)
{
- const char *name;
+ const char *id;
const char *author;
- g_autofree char *tmp = NULL;
+ g_autoptr(GrChef) chef = NULL;
g_autoptr(GArray) images = NULL;
const char *color;
GrRecipeStore *store;
- g_autoptr(GrChef) chef = NULL;
-
- g_set_object (&tile->recipe, recipe);
- if (!recipe)
- return;
store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
- name = gr_recipe_get_translated_name (recipe);
+ id = gr_recipe_get_id (recipe);
author = gr_recipe_get_author (recipe);
chef = gr_recipe_store_get_chef (store, author);
g_object_get (recipe, "images", &images, NULL);
if (images->len > 0) {
- g_autofree char *css = NULL;
GrRotatedImage *ri = &g_array_index (images, GrRotatedImage, 0);
- css = g_strdup_printf (" background: url('%s');\n"
- " background-size: 100%%;\n"
- " background-repeat: no-repeat;\n", ri->path);
- gr_utils_widget_set_css_simple (tile->box, css);
+ g_string_append_printf (css, "box.recipe.%s {\n", id);
+ g_string_append_printf (css, " background: url('%s');\n"
+ " background-size: 100%%;\n"
+ " background-repeat: no-repeat;\n", ri->path);
+ g_string_append (css, "}\n\n");
if (ri->dark_text)
color = "black";
@@ -96,23 +91,91 @@ recipe_tile_set_recipe (GrRecipeTile *tile,
}
if (color) {
- g_autofree char *css = NULL;
- css = g_strdup_printf (" color: %s;\n"
- " margin: 0 20px 0 20px;\n"
- " font-weight: bold;\n"
- " font-size: 24pt;\n", color);
- gr_utils_widget_set_css_simple (tile->label, css);
-
- g_free (css);
- css = g_strdup_printf (" color: %s;\n"
+ g_string_append_printf (css, "label.recipe.name.%s {\n", id);
+ g_string_append_printf (css, " color: %s;\n"
+ " margin: 0 20px 0 20px;\n"
+ " font-weight: bold;\n"
+ " font-size: 24pt;\n", color);
+ g_string_append (css, "}\n\n");
+
+ g_string_append_printf (css, "label.recipe.author.%s {\n", id);
+ g_string_append_printf (css, " color: %s;\n"
" margin: 10px 20px 20px 20px;\n"
" font-size: 12pt;\n", color);
- gr_utils_widget_set_css_simple (tile->author, css);
+ g_string_append (css, "}\n\n");
}
+}
- gtk_label_set_label (GTK_LABEL (tile->label), name);
- tmp = g_strdup_printf (_("by %s"), chef ? gr_chef_get_name (chef) : _("Anonymous"));
- gtk_label_set_label (GTK_LABEL (tile->author), tmp);
+static GtkCssProvider *provider = NULL;
+
+void
+gr_recipe_tile_recreate_css (void)
+{
+ GrRecipeStore *store;
+ g_autofree char **keys = NULL;
+ guint length;
+ g_autoptr(GString) css = NULL;
+ int i;
+
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+ keys = gr_recipe_store_get_recipe_keys (store, &length);
+
+ css = g_string_new ("");
+
+ for (i = 0; i < length; i++) {
+ g_autoptr (GrRecipe) recipe = NULL;
+ recipe = gr_recipe_store_get_recipe (store, keys[i]);
+ add_recipe_css (recipe, css);
+ }
+
+ if (provider == NULL) {
+ provider = gtk_css_provider_new ();
+ gtk_style_context_add_provider_for_screen (gdk_screen_get_default (),
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
+ }
+
+ gtk_css_provider_load_from_data (provider, css->str, css->len, NULL);
+}
+
+static void
+recipe_tile_set_recipe (GrRecipeTile *tile,
+ GrRecipe *recipe)
+{
+ GrRecipeStore *store;
+
+ store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
+
+ if (tile->recipe) {
+ const char *elem;
+ elem = gr_recipe_get_id (tile->recipe);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (tile->box), elem);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (tile->label), elem);
+ gtk_style_context_remove_class (gtk_widget_get_style_context (tile->author), elem);
+ }
+
+ g_set_object (&tile->recipe, recipe);
+
+ if (tile->recipe) {
+ const char *elem;
+ const char *name;
+ const char *author;
+ g_autoptr(GrChef) chef = NULL;
+ g_autofree char *tmp = NULL;
+
+ elem = gr_recipe_get_id (tile->recipe);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tile->box), elem);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tile->label), elem);
+ gtk_style_context_add_class (gtk_widget_get_style_context (tile->author), elem);
+
+ name = gr_recipe_get_translated_name (recipe);
+ author = gr_recipe_get_author (recipe);
+ chef = gr_recipe_store_get_chef (store, author);
+
+ gtk_label_set_label (GTK_LABEL (tile->label), name);
+ tmp = g_strdup_printf (_("by %s"), chef ? gr_chef_get_name (chef) : _("Anonymous"));
+ gtk_label_set_label (GTK_LABEL (tile->author), tmp);
+ }
}
static void
diff --git a/src/gr-recipe-tile.h b/src/gr-recipe-tile.h
index fd38761..66c1a29 100644
--- a/src/gr-recipe-tile.h
+++ b/src/gr-recipe-tile.h
@@ -33,4 +33,6 @@ G_DECLARE_FINAL_TYPE (GrRecipeTile, gr_recipe_tile, GR, RECIPE_TILE, GtkButton)
GtkWidget *gr_recipe_tile_new (GrRecipe *recipe);
GrRecipe *gr_recipe_tile_get_recipe (GrRecipeTile *tile);
+void gr_recipe_tile_recreate_css (void);
+
G_END_DECLS
diff --git a/src/gr-recipe-tile.ui b/src/gr-recipe-tile.ui
index 71ed006..1621879 100644
--- a/src/gr-recipe-tile.ui
+++ b/src/gr-recipe-tile.ui
@@ -40,6 +40,7 @@
<property name="max-width-chars">12</property>
<style>
<class name="recipe"/>
+ <class name="name"/>
</style>
</object>
</child>
@@ -53,6 +54,7 @@
<property name="max-width-chars">12</property>
<style>
<class name="recipe"/>
+ <class name="author"/>
</style>
</object>
</child>
diff --git a/src/gr-recipes-page.c b/src/gr-recipes-page.c
index 5c2d12e..80c32fc 100644
--- a/src/gr-recipes-page.c
+++ b/src/gr-recipes-page.c
@@ -122,6 +122,8 @@ gr_recipes_page_init (GrRecipesPage *page)
populate_diets_from_store (page);
populate_recipes_from_store (page);
populate_chefs_from_store (page);
+ gr_recipe_tile_recreate_css ();
+ gr_chef_tile_recreate_css ();
connect_store_signals (page);
}
@@ -271,6 +273,8 @@ repopulate_recipes (GrRecipesPage *self)
{
populate_recipes_from_store (self);
populate_diets_from_store (self);
+ gr_recipe_tile_recreate_css ();
+ gr_chef_tile_recreate_css ();
}
static void
@@ -281,6 +285,8 @@ populate_chefs_from_store (GrRecipesPage *self)
guint length;
int i;
+ gr_chef_tile_recreate_css ();
+
container_remove_all (GTK_CONTAINER (self->chefs_box));
store = gr_app_get_recipe_store (GR_APP (g_application_get_default ()));
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]