Complete.Org: Mailing Lists: Archives: freeciv-dev: August 2005:
[Freeciv-Dev] (PR#13589) Theme support
Home

[Freeciv-Dev] (PR#13589) Theme support

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
Subject: [Freeciv-Dev] (PR#13589) Theme support
From: "Mateusz Stefek" <mstefek@xxxxxxxxx>
Date: Tue, 2 Aug 2005 00:10:07 -0700
Reply-to: bugs@xxxxxxxxxxx

<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

[Prev in Thread] Current Thread [Next in Thread]