diff options
Diffstat (limited to 'src/gui/core')
| -rw-r--r-- | src/gui/core/core.c | 12 | ||||
| -rw-r--r-- | src/gui/core/theme.c | 294 | ||||
| -rw-r--r-- | src/gui/core/theme.h | 11 | 
3 files changed, 154 insertions, 163 deletions
| diff --git a/src/gui/core/core.c b/src/gui/core/core.c index 8783783..a0904f8 100644 --- a/src/gui/core/core.c +++ b/src/gui/core/core.c @@ -90,10 +90,16 @@ bool load_all_gui_components(void)  bool complete_loading_of_all_gui_components(GGenConfig *config)  {      bool result;                            /* Bilan à faire remonter      */ +    const char *name;                       /* Nom du thème recherché      */      GtkTiledGrid *grid;                     /* Composant d'affichage       */      GPanelItem *welcome;                    /* Panneau d'accueil           */ -    load_extra_gtk_theme(); +    result = g_generic_config_get_value(config, MPK_INTERNAL_THEME, &name); +    if (!result) goto no_theme; + +    load_all_themes(); + +    apply_gtk_theme(name);      result = load_segment_rendering_parameters(); @@ -119,6 +125,8 @@ bool complete_loading_of_all_gui_components(GGenConfig *config)      gtk_tiled_grid_restore_positions(grid, config); + no_theme: +      return result;  } @@ -140,4 +148,6 @@ void unload_all_gui_components(void)  {      exit_segment_content_hash_table(); +    unload_all_themes(); +  } diff --git a/src/gui/core/theme.c b/src/gui/core/theme.c index 77eff7f..83bcf4e 100644 --- a/src/gui/core/theme.c +++ b/src/gui/core/theme.c @@ -39,22 +39,16 @@  #include <i18n.h> +#include "../theme.h"  #include "../../common/extstr.h"  #include "../../common/xdg.h"  #include "../../core/logs.h" -#include "../../core/params.h"  #include "../../plugins/pglist.h" -/* Parcourt tous les répertoires connus pour trouver un thème. */ -static bool browse_themes_directories(GdkScreen *, const char *, gboolean); - -/* Parcourt un répertoire donné à la recherche d'un thème. */ -static bool look_for_named_theme(GdkScreen *, const char *, const char *, gboolean); - -/* Ajoute les définitions CSS à partir d'un chemin donné. */ -static bool load_css_content(GdkScreen *, const char *, gboolean); +/* Parcourt un répertoire donné à la recherche de thèmes. */ +static void look_for_editor_themes(const char *);  /* Parcourt tous les greffons à la recherche de définitions CSS. */  static bool extend_with_plugins_themes(GdkScreen *, gboolean); @@ -72,56 +66,15 @@ static const char *_themes_directories[] = {  }; +/* Liste de thèmes utilisables */ +static GEditorTheme **_themes = NULL; +static size_t _theme_count = 0; -/****************************************************************************** -*                                                                             * -*  Paramètres  : -                                                            * -*                                                                             * -*  Description : Charge le thème GTK pour les composants spécifiques.         * -*                                                                             * -*  Retour      : true ou false selon le bilan de l'opération.                 * -*                                                                             * -*  Remarques   : -                                                            * -*                                                                             * -******************************************************************************/ - -bool load_extra_gtk_theme(void) -{ -    bool result;                            /* Bilan à faire remonter      */ -    const char *name;                       /* Nom du thème recherché      */ -    GdkScreen *screen;                      /* Ecran(s) concerné(s)        */ -    GtkSettings *settings;                  /* Propriétés du système       */ -    gboolean dark;                          /* Envie d'un thème sombre ?   */ - -    result = false; - -    if (!g_generic_config_get_value(get_main_configuration(), MPK_INTERNAL_THEME, &name)) -        goto legt_done; - -    screen = gdk_screen_get_default(); - -    settings = gtk_settings_get_for_screen(screen); - -    g_object_get(settings, "gtk-application-prefer-dark-theme", &dark, NULL); - -    result = browse_themes_directories(screen, name, dark); - -    if (result) -        result = extend_with_plugins_themes(screen, dark); - - legt_done: - -    return result; - -} -  /******************************************************************************  *                                                                             * -*  Paramètres  : screen = écran visé par le chargement d'un thème.            * -*                name   = nom du thème recherché, et donc de son répertoire.  * -*                dark   = indique une préférence pour la variante foncée.     * +*  Paramètres  : -                                                            *  *                                                                             *  *  Description : Parcourt tous les répertoires connus pour trouver un thème.  *  *                                                                             * @@ -131,15 +84,12 @@ bool load_extra_gtk_theme(void)  *                                                                             *  ******************************************************************************/ -static bool browse_themes_directories(GdkScreen *screen, const char *name, gboolean dark) +void load_all_themes(void)  { -    bool result;                            /* Bilan à renvoyer            */      char *suffix;                           /* Fin du répertoire personnel */      char *owndir;                           /* Thèmes personnels ?         */      const char **iter;                      /* Boucle de parcours          */ -    result = false; -      /* Répertoire de l'utilisateur en premier ! */      suffix = strdup("chrysalide"); @@ -152,74 +102,70 @@ static bool browse_themes_directories(GdkScreen *screen, const char *name, gbool      if (owndir != NULL)      { -        result = look_for_named_theme(screen, owndir, name, dark); - +        look_for_editor_themes(owndir);          free(owndir); -      }      /* Parcours des autres répertoires classiques au besoin */ -    for (iter = _themes_directories; *iter != NULL && !result; iter++) -        result = look_for_named_theme(screen, *iter, name, dark); - -    return result; +    for (iter = _themes_directories; *iter != NULL; iter++) +        look_for_editor_themes(*iter);  }  /******************************************************************************  *                                                                             * -*  Paramètres  : screen  = écran visé par le chargement d'un thème.           * -*                dirname = chemin du répertoire où effectuer des recherches.  * -*                name    = nom du thème recherché, et donc de son répertoire. * -*                dark    = indique une préférence pour la variante foncée.    * +*  Paramètres  : dirname = chemin du répertoire où effectuer des recherches.  *  *                                                                             * -*  Description : Parcourt un répertoire donné à la recherche d'un thème.      * +*  Description : Parcourt un répertoire donné à la recherche de thèmes.       *  *                                                                             * -*  Retour      : Bilan de l'opération.                                        * +*  Retour      : -                                                            *  *                                                                             *  *  Remarques   : -                                                            *  *                                                                             *  ******************************************************************************/ -static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const char *name, gboolean dark) +static void look_for_editor_themes(const char *dirname)  { -    bool result;                            /* Bilan à renvoyer            */ -    char *path;                             /* Chemin d'accès à essayer    */ -    int ret;                                /* Bilan d'un appel            */      int dirfd;                              /* Canal de lecture            */      struct dirent **namelist;               /* Liste des trouvailles       */      int count;                              /* Nombre de fichiers trouvés  */      int i;                                  /* Boucle de parcours          */ +    struct dirent *entry;                   /* Raccourci d'usage           */ +    int ret;                                /* Bilan d'un appel            */      char *filename;                         /* Chemin d'accès constitué    */ +    GEditorTheme *theme;                    /* Nouveau thème valide        */ -    result = false; - -    ret = asprintf(&path, "%s" G_DIR_SEPARATOR_S "%s", dirname, name); -    if (ret == -1) goto lfnt_done; +    dirfd = open(dirname, O_RDONLY | O_DIRECTORY); +    if (dirfd == -1) goto not_found; -    dirfd = open(path, O_RDONLY | O_DIRECTORY); -    if (dirfd == -1) goto lfnt_not_found; +    count = scandirat(dirfd, ".", &namelist, NULL, alphasort); -    int keep_css_only(const struct dirent *entry) +    for (i = 0; i < count; i++)      { -        return (entry->d_type == DT_REG -                && endswith(entry->d_name, ".css") -                && !endswith(entry->d_name, "-dark.css") ? 1 : 0); +        entry = namelist[i]; -    } +        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) +            continue; -    count = scandirat(dirfd, ".", &namelist, keep_css_only, alphasort); +        ret = asprintf(&filename, "%s%s%s", dirname, G_DIR_SEPARATOR_S, entry->d_name); +        if (ret == -1) continue; -    result = (count > 0); +        if (entry->d_type == DT_DIR) +            look_for_editor_themes(filename); -    for (i = 0; i < count && result; i++) -    { -        ret = asprintf(&filename, "%s%s%s", path, G_DIR_SEPARATOR_S, namelist[i]->d_name); -        if (ret == -1) continue; +        else if (entry->d_type == DT_REG) +        { +            theme = g_editor_theme_new(filename, true); -        result = load_css_content(screen, filename, dark); +            if (theme != NULL) +            { +                _themes = realloc(_themes, ++_theme_count * sizeof(GEditorTheme *)); +                _themes[_theme_count - 1] = theme; +            } + +        }          free(filename); @@ -230,11 +176,80 @@ static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const c      close(dirfd); - lfnt_not_found: + not_found: -    free(path); +    ; - lfnt_done: +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : -                                                            * +*                                                                             * +*  Description : Décharge tous les thèmes référencés en mémoire.              * +*                                                                             * +*  Retour      : -                                                            * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +void unload_all_themes(void) +{ +    size_t i;                               /* Boucle de parcours          */ + +    for (i = 0; i < _theme_count; i++) +        g_object_unref(G_OBJECT(_themes[i])); + +    if (_themes != NULL) +        free(_themes); + +    _theme_count = 0; + +} + + +/****************************************************************************** +*                                                                             * +*  Paramètres  : name = désignation du thème GTK à charger.                   * +*                                                                             * +*  Description : Charge le thème GTK pour les composants spécifiques.         * +*                                                                             * +*  Retour      : true ou false selon le bilan de l'opération.                 * +*                                                                             * +*  Remarques   : -                                                            * +*                                                                             * +******************************************************************************/ + +bool apply_gtk_theme(const char *name) +{ +    bool result;                            /* Bilan à faire remonter      */ +    size_t i;                               /* Boucle de parcours          */ +    GdkScreen *screen;                      /* Ecran(s) concerné(s)        */ +    GtkSettings *settings;                  /* Propriétés du système       */ +    gboolean dark;                          /* Envie d'un thème sombre ?   */ + +    result = false; + +    for (i = 0; i < _theme_count; i++) +        if (strcmp(name, g_editor_theme_get_name(_themes[i])) == 0) +        { +            result = true; +            break; +        } + +    if (result) +    { +        screen = gdk_screen_get_default(); + +        settings = gtk_settings_get_for_screen(screen); + +        g_object_get(settings, "gtk-application-prefer-dark-theme", &dark, NULL); + +        g_editor_theme_load(_themes[i], screen, dark); + +    }      return result; @@ -255,16 +270,12 @@ static bool look_for_named_theme(GdkScreen *screen, const char *dirname, const c  *                                                                             *  ******************************************************************************/ -static bool load_css_content(GdkScreen *screen, const char *path, gboolean dark) +GtkCssProvider *load_css_content(GdkScreen *screen, const char *path)  { -    bool result;                            /* Bilan à renvoyer            */ -    GtkCssProvider *provider;               /* Nouveau fournisseur CSS     */ -    char *dark_path;                        /* Version sombre du chemin    */ +    GtkCssProvider *result;                 /* Fournisseur à renvoyer      */      GFile *file;                            /* Fichier à charger           */      GError *error;                          /* Relevé d'éventuelles erreurs*/ -    result = false; -      /**       * Comme GTK exporte les images sous forme de données encodées en base 64       * (cf. gtk_css_image_surface_print()) et ne sait pas recharger ensuite @@ -278,75 +289,32 @@ static bool load_css_content(GdkScreen *screen, const char *path, gboolean dark)       * Ce constat est valable pour la version 3.22.11-1 de Debian, au moins.       */ -    if (dark) -    { -        provider = gtk_css_provider_new(); - -        error = NULL; +    result = gtk_css_provider_new(); -        dark_path = strdup(path); -        dark_path = strrpl(dark_path, ".css", "-dark.css"); +    error = NULL; -        if (strstr(path, "://") != NULL) -            file = g_file_new_for_uri(dark_path); -        else -            file = g_file_new_for_path(dark_path); +    assert(strstr(path, "://") != NULL); -        gtk_css_provider_load_from_file(provider, file, &error); +    file = g_file_new_for_uri(path); -        g_object_unref(G_OBJECT(file)); +    gtk_css_provider_load_from_file(result, file, &error); -        if (error == NULL) -        { -            log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), dark_path); +    g_object_unref(G_OBJECT(file)); -            gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), -                                                      GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - -            result = true; - -        } -        else -            g_error_free(error); - -        free(dark_path); +    if (error == NULL) +    { +        log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), path); -        g_object_unref(G_OBJECT(provider)); +        gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(result), +                                                  GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);      } - -    if (!result) +    else      { -        provider = gtk_css_provider_new(); - -        error = NULL; - -        if (strstr(path, "://") != NULL) -            file = g_file_new_for_uri(path); -        else -            file = g_file_new_for_path(path); - -        gtk_css_provider_load_from_file(provider, file, &error); - -        g_object_unref(G_OBJECT(file)); +        log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions from '%s'"), path); +        g_error_free(error); -        if (error == NULL) -        { -            log_variadic_message(LMT_INFO, _("Loaded CSS definitions from '%s'"), path); - -            gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), -                                                      GTK_STYLE_PROVIDER_PRIORITY_APPLICATION); - -            result = true; - -        } -        else -        { -            log_variadic_message(LMT_ERROR, _("Failed to load CSS definitions from '%s'"), path); -            g_error_free(error); -        } - -        g_object_unref(G_OBJECT(provider)); +        g_object_unref(G_OBJECT(result));      } @@ -374,6 +342,7 @@ static bool extend_with_plugins_themes(GdkScreen *screen, gboolean dark)      char **resources;                       /* Fichiers supplémentaires    */      size_t count;                           /* Nombre de ces fichiers      */      size_t i;                               /* Boucle de parcours          */ +    GtkCssProvider *provider;               /* Nouveau fournisseur CSS     */      result = true; @@ -384,8 +353,11 @@ static bool extend_with_plugins_themes(GdkScreen *screen, gboolean dark)      for (i = 0; i < count && result; i++)      { -        result = load_css_content(screen, resources[i], dark); +        provider = load_css_content(screen, resources[i]); +        g_clear_object(&provider); +          free(resources[i]); +      }      if (resources != NULL) diff --git a/src/gui/core/theme.h b/src/gui/core/theme.h index dfa7d34..52c6fb0 100644 --- a/src/gui/core/theme.h +++ b/src/gui/core/theme.h @@ -31,8 +31,17 @@ +/* Parcourt tous les répertoires connus pour trouver un thème. */ +void load_all_themes(void); + +/* Décharge tous les thèmes référencés en mémoire. */ +void unload_all_themes(void); +  /* Charge le thème GTK pour les composants spécifiques. */ -bool load_extra_gtk_theme(void); +bool apply_gtk_theme(const char *); + +/* Ajoute les définitions CSS à partir d'un chemin donné. */ +GtkCssProvider *load_css_content(GdkScreen *, const char *); | 
