[Freeciv-Dev] (PR#13589) Theme support
[Top] [All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
<URL: http://bugs.freeciv.org/Ticket/Display.html?id=13589 >
This is a first patch which demostrates theme support for the client.
Only gtk2 use it, but the engine is quite general.
The client searches for themes in the following directories:
./themes
data/themes
~/.freeciv/themes
{prefix}/share/freeciv/themes
~/.themes
/usr/share/themes
Last two directories are gui-gtk2 specific.
The patch is written to help art developers to create some cool themes
for Freeciv - see the work of aneglus on the forum.
The theme engine is used in a way that a user can change a theme in the
local options dialog.
In the future the client could switch themes when a city style changes.
Some nice themes can be downloaded at: http://art.gnome.org/themes/gtk2/
--
mateusz
diff -urN -Xfreeciv/diff_ignore freeciv/client/civclient.c
themes/client/civclient.c
--- freeciv/client/civclient.c 2005-08-01 08:52:06.000000000 +0200
+++ themes/client/civclient.c 2005-08-01 09:27:40.000000000 +0200
@@ -68,6 +68,7 @@
#include "plrdlg_g.h"
#include "repodlgs_g.h"
#include "tilespec.h"
+#include "themes_common.h"
#include "civclient.h"
@@ -315,6 +316,7 @@
chatline_common_init();
message_options_init();
init_player_dlg_common();
+ init_themes();
settable_options_init();
load_general_options();
diff -urN -Xfreeciv/diff_ignore freeciv/client/gui-gtk-2.0/gui_main.c
themes/client/gui-gtk-2.0/gui_main.c
--- freeciv/client/gui-gtk-2.0/gui_main.c 2005-07-27 09:38:04.000000000
+0200
+++ themes/client/gui-gtk-2.0/gui_main.c 2005-08-01 09:35:18.000000000
+0200
@@ -1084,7 +1084,7 @@
gtk_rc_parse(str);
g_free(str);
}
-
+
toplevel = gtk_window_new(GTK_WINDOW_TOPLEVEL);
g_signal_connect(toplevel, "key_press_event",
G_CALLBACK(toplevel_handler), NULL);
@@ -1206,7 +1206,7 @@
init_mapcanvas_and_overview();
set_client_state(CLIENT_PRE_GAME_STATE);
-
+
gtk_main();
spaceship_dialog_done();
diff -urN -Xfreeciv/diff_ignore freeciv/client/gui-gtk-2.0/Makefile.am
themes/client/gui-gtk-2.0/Makefile.am
--- freeciv/client/gui-gtk-2.0/Makefile.am 2005-03-23 19:13:21.000000000
+0100
+++ themes/client/gui-gtk-2.0/Makefile.am 2005-08-01 09:27:40.000000000
+0200
@@ -85,6 +85,7 @@
spaceshipdlg.h \
sprite.c \
sprite.h \
+ themes.c \
wldlg.c \
wldlg.h
diff -urN -Xfreeciv/diff_ignore freeciv/client/gui-gtk-2.0/themes.c
themes/client/gui-gtk-2.0/themes.c
--- freeciv/client/gui-gtk-2.0/themes.c 1970-01-01 01:00:00.000000000 +0100
+++ themes/client/gui-gtk-2.0/themes.c 2005-08-01 10:08:23.000000000 +0200
@@ -0,0 +1,127 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <dirent.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+#include <gtk/gtk.h>
+
+#include "mem.h"
+#include "support.h"
+
+#include "themes_common.h"
+#include "themes_g.h"
+
+/*****************************************************************************
+ Loads a gtk theme directory/theme_name
+*****************************************************************************/
+void gui_load_theme(const char* directory, const char* theme_name)
+{
+ char buf[1024];
+ my_snprintf(buf, sizeof(buf), "%s/%s/gtk-2.0/gtkrc", directory, theme_name);
+
+ gchar *default_files[] = {buf, NULL};
+ gtk_rc_set_default_files(default_files);
+/*
+ gtk_rc_parse(buf);
+ gtk_rc_reset_styles(gtk_settings_get_default()); */
+ gtk_rc_reparse_all_for_settings(gtk_settings_get_default(), TRUE);
+}
+
+/*****************************************************************************
+ Each gui has its own themes directories.
+ For gtk2 these are:
+ - /usr/share/themes
+ - ~/.themes
+ Returns an array containing these strings and sets array size in count.
+ The caller is responsible for freeing the array and the paths.
+*****************************************************************************/
+char** get_gui_specific_themes_directories(int* count)
+{
+ gchar* standard_dir;
+ char* home_dir;
+ char** directories = fc_malloc(sizeof(char*) * 2);
+
+ *count = 0;
+
+ standard_dir = gtk_rc_get_theme_dir();
+ directories[*count] = mystrdup(standard_dir);
+ (*count)++;
+ g_free(standard_dir);
+
+ home_dir = user_home_dir();
+ if (home_dir) {
+ char buf[1024];
+ my_snprintf(buf, sizeof(buf), "%s/.themes/", home_dir);
+ directories[*count] = mystrdup(buf);
+ (*count)++;
+ }
+
+ return directories;
+}
+
+/*****************************************************************************
+ Return an array of names of usable themes in the given directory.
+ Array size is stored in count.
+ Useable theme for gtk+ is a directory which contains file gtk-2.0/gtkrc.
+ The caller is responsible for freeing the array and the names
+*****************************************************************************/
+char** get_useable_themes_in_directory(const char* directory,
+ int* count)
+{
+ DIR *dir;
+ struct dirent *entry;
+ int t_size = 2;
+ char** theme_names = fc_malloc(sizeof(char*) * 2);
+
+ *count = 0;
+
+ dir = opendir(directory);
+ if (!dir) {
+ return theme_names;
+ }
+
+ while ((entry = readdir(dir))) {
+ char buf[1024];
+ struct stat stat_result;
+
+ my_snprintf(buf, sizeof(buf),
+ "%s/%s/gtk-2.0/gtkrc", directory, entry->d_name);
+
+ if (stat(buf, &stat_result) != 0) {
+ /* File doesn't exist */
+ continue;
+ }
+ if (!S_ISREG(stat_result.st_mode)) {
+ /* Not a regular file */
+ continue;
+ }
+ /* Otherwise it's ok */
+ if (*count == t_size) {
+ theme_names = fc_realloc(theme_names, t_size * 2 * sizeof(char*));
+ t_size *= 2;
+ }
+
+ theme_names[*count] = mystrdup(entry->d_name);
+ (*count)++;
+ }
+
+ closedir(dir);
+
+ return theme_names;
+}
diff -urN -Xfreeciv/diff_ignore freeciv/client/include/Makefile.am
themes/client/include/Makefile.am
--- freeciv/client/include/Makefile.am 2005-03-23 18:56:54.000000000 +0100
+++ themes/client/include/Makefile.am 2005-08-01 09:27:40.000000000 +0200
@@ -26,4 +26,5 @@
repodlgs_g.h \
spaceshipdlg_g.h \
sprite_g.h \
+ themes_g.h \
wldlg_g.h
diff -urN -Xfreeciv/diff_ignore freeciv/client/include/themes_g.h
themes/client/include/themes_g.h
--- freeciv/client/include/themes_g.h 1970-01-01 01:00:00.000000000 +0100
+++ themes/client/include/themes_g.h 2005-08-01 09:27:40.000000000 +0200
@@ -0,0 +1,20 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__THEMES_G_H
+#define FC__THEMES_G_H
+
+void gui_load_theme(const char* directory, const char* theme_name);
+char** get_gui_specific_themes_directories(int *count);
+char** get_useable_themes_in_directory(const char* directory, int* count);
+
+#endif
diff -urN -Xfreeciv/diff_ignore freeciv/client/Makefile.am
themes/client/Makefile.am
--- freeciv/client/Makefile.am 2005-05-09 20:42:18.000000000 +0200
+++ themes/client/Makefile.am 2005-08-01 09:27:40.000000000 +0200
@@ -171,6 +171,8 @@
reqtree.h \
text.c \
text.h \
+ themes_common.c \
+ themes_common.h \
tilespec.c \
tilespec.h \
audio.c \
diff -urN -Xfreeciv/diff_ignore freeciv/client/options.c themes/client/options.c
--- freeciv/client/options.c 2005-08-01 08:18:34.000000000 +0200
+++ themes/client/options.c 2005-08-01 09:27:40.000000000 +0200
@@ -37,6 +37,7 @@
#include "mapview_common.h"
#include "overview_common.h"
#include "plrdlg_common.h"
+#include "themes_common.h"
#include "tilespec.h"
#include "options.h"
@@ -48,6 +49,7 @@
int default_server_port = DEFAULT_SOCK_PORT;
char default_metaserver[512] = METALIST_ADDR;
char default_tileset_name[512] = "\0";
+char default_theme_name[512] = "\0";
char default_sound_set_name[512] = "stdsounds";
char default_sound_plugin_name[512] = "\0";
@@ -133,7 +135,10 @@
"parameter."),
COC_GRAPHICS,
get_tileset_list, tilespec_reread_callback),
-
+ GEN_STR_OPTION(default_theme_name, N_("Theme"),
+ N_("TODO"),
+ COC_GRAPHICS,
+ get_themes_list, theme_reread_callback),
GEN_BOOL_OPTION_CB(solid_color_behind_units,
N_("Solid unit background color"),
N_("Setting this option will cause units on the map "
diff -urN -Xfreeciv/diff_ignore freeciv/client/options.h themes/client/options.h
--- freeciv/client/options.h 2005-07-30 09:03:03.000000000 +0200
+++ themes/client/options.h 2005-08-01 09:27:40.000000000 +0200
@@ -21,6 +21,7 @@
extern int default_server_port;
extern char default_metaserver[512];
extern char default_tileset_name[512];
+extern char default_theme_name[512];
extern char default_sound_set_name[512];
extern char default_sound_plugin_name[512];
diff -urN -Xfreeciv/diff_ignore freeciv/client/themes_common.c
themes/client/themes_common.c
--- freeciv/client/themes_common.c 1970-01-01 01:00:00.000000000 +0100
+++ themes/client/themes_common.c 2005-08-01 09:27:40.000000000 +0200
@@ -0,0 +1,165 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+***********************************************************************/
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <assert.h>
+
+#include <unistd.h>
+#include <string.h>
+#include <sys/stat.h>
+
+
+#include "mem.h"
+#include "shared.h"
+#include "support.h"
+
+#include "themes_common.h"
+
+#include "themes_g.h"
+
+struct theme_directory
+{
+ char* path;
+ char** themes;
+ int num_themes;
+};
+
+static int num_directories;
+struct theme_directory* directories;
+
+/****************************************************************************
+ Initialized themes data
+****************************************************************************/
+void init_themes(void)
+{
+ int t_size = 2;
+ char** directories_paths = fc_malloc(sizeof(char*) * 2);
+ int count = 0;
+ int i;
+ char* path;
+ char* tok;
+ struct stat stat_result;
+ int gui_directories_count;
+ char** gui_directories;
+
+ path = mystrdup(DEFAULT_DATA_PATH);
+ for (tok = strtok(path, ":;");
+ tok;
+ tok = strtok(NULL, ":;")) {
+ char buf[128];
+
+ my_snprintf(buf, sizeof(buf), "%s/themes", tok);
+ if (stat(buf, &stat_result) != 0) {
+ continue;
+ }
+ if (!S_ISDIR(stat_result.st_mode)) {
+ continue;
+ }
+
+ if (t_size == count) {
+ directories_paths =
+ fc_realloc(directories_paths, t_size * 2 * sizeof(char*));
+ t_size *= 2;
+ }
+
+ directories_paths[count] = mystrdup(buf);
+ count++;
+ }
+ free(path);
+
+ /* Add gui specific directories */
+ gui_directories =
+ get_gui_specific_themes_directories(&gui_directories_count);
+
+ for (i = 0; i < gui_directories_count; i++) {
+ if (t_size == count) {
+ directories_paths =
+ fc_realloc(directories_paths, t_size * 2 * sizeof(char*));
+ t_size *= 2;
+ }
+ directories_paths[count++] = gui_directories[i];
+ }
+ free(gui_directories);
+
+ /* Load useable themes in those directories */
+ directories = fc_malloc(sizeof(struct theme_directory) * count);
+ for (i = 0; i < count; i++) {
+ directories[i].path = directories_paths[i];
+
+ directories[i].themes =
+ get_useable_themes_in_directory(directories_paths[i],
+ &(directories[i].num_themes));
+ }
+ num_directories = count;
+ free(directories_paths);
+}
+
+/****************************************************************************
+ Return an array of useable theme names. The array is NULL terminated and
+ the caller is responsible for freeing the array.
+****************************************************************************/
+const char** get_themes_list(void)
+{
+ int size = 0;
+ int i, j, k, c;
+ const char** themes;
+
+ for (i = 0; i < num_directories; i++) {
+ size += directories[i].num_themes;
+ }
+
+ themes = fc_malloc(sizeof(char*) * (size + 1));
+
+ c = 0;
+ for (i = 0; i < num_directories; i++) {
+ for (j = 0; j < directories[i].num_themes; j++) {
+ for (k = 0; k < c; k++) {
+ if (strcmp(themes[k], directories[i].themes[j]) == 0) {
+ break;
+ }
+ }
+ if (k == c) {
+ themes[c++] = directories[i].themes[j];
+ }
+ }
+ }
+ themes[c] = NULL;
+ return themes;
+}
+
+/****************************************************************************
+ Loads a theme with the given name.
+****************************************************************************/
+void load_theme(const char* theme_name)
+{
+ int i, j;
+ for (i = 0; i < num_directories; i++) {
+ for (j = 0; j < directories[i].num_themes; j++) {
+ if (strcmp(theme_name, directories[i].themes[j]) == 0) {
+ gui_load_theme(directories[i].path, directories[i].themes[j]);
+ return;
+ }
+ }
+ }
+}
+
+/****************************************************************************
+ Wrapper for load_theme. It's is used by local options dialog
+****************************************************************************/
+void theme_reread_callback(struct client_option *option)
+{
+ assert(option->p_string_value && *option->p_string_value != '\0');
+ load_theme(option->p_string_value);
+}
diff -urN -Xfreeciv/diff_ignore freeciv/client/themes_common.h
themes/client/themes_common.h
--- freeciv/client/themes_common.h 1970-01-01 01:00:00.000000000 +0100
+++ themes/client/themes_common.h 2005-08-01 09:27:40.000000000 +0200
@@ -0,0 +1,21 @@
+/**********************************************************************
+ Freeciv - Copyright (C) 2005 The Freeciv Team
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2, or (at your option)
+ any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+***********************************************************************/
+#ifndef FC__THEMES_COMMON_H
+#define FC__THEMES_COMMON_H
+#include "options.h"
+
+void init_themes(void);
+const char** get_themes_list(void);
+void load_theme(const char* theme_name);
+void theme_reread_callback(struct client_option *option);
+#endif
- [Freeciv-Dev] (PR#13589) Theme support,
Mateusz Stefek <=
|
|