Replaced deprecated gtk_menu_popup() calls with modern constructs in gtk3.22-client
[freeciv.git] / client / gui-gtk-3.0 / themes.c
blobc64995f7f234c71b98ebd11ddb6faf278f10d19b
1 /**********************************************************************
2 Freeciv - Copyright (C) 2005 The Freeciv Team
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 2, or (at your option)
6 any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12 ***********************************************************************/
13 #ifdef HAVE_CONFIG_H
14 #include <fc_config.h>
15 #endif
17 #include <dirent.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
22 #include <gtk/gtk.h>
24 /* utility */
25 #include "mem.h"
26 #include "string_vector.h"
27 #include "support.h"
29 /* client */
30 #include "themes_common.h"
32 /* gui-gtk-3.0 */
33 #include "gui_main.h"
35 #include "themes_g.h"
37 /*****************************************************************************
38 Loads a gtk theme directory/theme_name
39 *****************************************************************************/
40 void gui_load_theme(const char *directory, const char *theme_name)
42 static GtkCssProvider *fc_css_provider = NULL;
43 GError *error = NULL;
44 char buf[strlen(directory) + strlen(theme_name) + 32];
46 if (fc_css_provider == NULL) {
47 fc_css_provider = gtk_css_provider_new();
48 gtk_style_context_add_provider(gtk_widget_get_style_context(toplevel),
49 GTK_STYLE_PROVIDER(fc_css_provider),
50 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
53 /* Gtk theme is a directory containing gtk-3.0/gtk.css file */
54 fc_snprintf(buf, sizeof(buf), "%s/%s/gtk-3.0/gtk.css", directory,
55 theme_name);
57 gtk_css_provider_load_from_file(fc_css_provider, g_file_new_for_path(buf), &error);
59 if (error) {
60 g_warning("%s\n", error->message);
63 gtk_style_context_invalidate(gtk_widget_get_style_context(toplevel));
66 /*****************************************************************************
67 Clears a theme (sets default system theme)
68 *****************************************************************************/
69 void gui_clear_theme(void)
71 bool theme_loaded;
73 /* try to load user defined theme */
74 theme_loaded = load_theme(gui_options.gui_gtk3_default_theme_name);
76 /* no user defined theme loaded -> try to load Freeciv default theme */
77 if (!theme_loaded) {
78 theme_loaded = load_theme(FC_GTK3_DEFAULT_THEME_NAME);
79 if (theme_loaded) {
80 sz_strlcpy(gui_options.gui_gtk3_default_theme_name, FC_GTK3_DEFAULT_THEME_NAME);
84 /* still no theme loaded -> load system default theme */
85 if (!theme_loaded) {
86 gtk_style_context_add_provider_for_screen(
87 gtk_widget_get_screen(toplevel),
88 GTK_STYLE_PROVIDER(gtk_css_provider_get_default()),
89 GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
93 /*****************************************************************************
94 Each gui has its own themes directories.
95 For gtk3 these are:
96 - /usr/share/themes
97 - ~/.themes
98 Returns an array containing these strings and sets array size in count.
99 The caller is responsible for freeing the array and the paths.
100 *****************************************************************************/
101 char **get_gui_specific_themes_directories(int *count)
103 gchar *standard_dir;
104 char *home_dir;
105 const struct strvec *data_dirs = get_data_dirs();
106 char **directories = fc_malloc((2 + strvec_size(data_dirs))
107 * sizeof(char *));
109 *count = 0;
111 /* Freeciv-specific GTK3 themes directories */
112 strvec_iterate(data_dirs, dir_name) {
113 char buf[strlen(dir_name) + strlen("/themes/gui-gtk-3.0") + 1];
115 fc_snprintf(buf, sizeof(buf), "%s/themes/gui-gtk-3.0", dir_name);
117 directories[(*count)++] = fc_strdup(buf);
118 } strvec_iterate_end;
120 /* standard GTK+ themes directory */
121 #ifdef CROSSER
122 standard_dir = "../share/themes";
123 #else /* CROSSER */
124 standard_dir = "/usr/share/themes";
125 #endif /* CROSSER */
126 directories[(*count)++] = fc_strdup(standard_dir);
128 /* user GTK+ themes directory (~/.themes) */
129 home_dir = user_home_dir();
130 if (home_dir) {
131 char buf[strlen(home_dir) + 16];
133 fc_snprintf(buf, sizeof(buf), "%s/.themes/", home_dir);
134 directories[(*count)++] = fc_strdup(buf);
137 return directories;
140 /*****************************************************************************
141 Return an array of names of usable themes in the given directory.
142 Array size is stored in count.
143 Useable theme for gtk+ is a directory which contains file gtk-3.0/gtk.css.
144 The caller is responsible for freeing the array and the names
145 *****************************************************************************/
146 char **get_useable_themes_in_directory(const char *directory, int *count)
148 DIR *dir;
149 struct dirent *entry;
151 char **theme_names = fc_malloc(sizeof(char *) * 2);
152 /* Allocated memory size */
153 int t_size = 2;
156 *count = 0;
158 dir = fc_opendir(directory);
159 if (!dir) {
160 /* This isn't directory or we can't list it */
161 return theme_names;
164 while ((entry = readdir(dir))) {
165 char buf[strlen(directory) + strlen(entry->d_name) + 32];
166 struct stat stat_result;
168 fc_snprintf(buf, sizeof(buf),
169 "%s/%s/gtk-3.0/gtk.css", directory, entry->d_name);
171 if (fc_stat(buf, &stat_result) != 0) {
172 /* File doesn't exist */
173 continue;
176 if (!S_ISREG(stat_result.st_mode)) {
177 /* Not a regular file */
178 continue;
181 /* Otherwise it's ok */
183 /* Increase array size if needed */
184 if (*count == t_size) {
185 theme_names = fc_realloc(theme_names, t_size * 2 * sizeof(char *));
186 t_size *= 2;
189 theme_names[*count] = fc_strdup(entry->d_name);
190 (*count)++;
193 closedir(dir);
195 return theme_names;