Adding upstream version 0.6.2.
[debian/lxappearance.git] / src / widget-theme.c
1 /*
2 * widget-theme.c
3 *
4 * Copyright 2010 PCMan <pcman.tw@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 * MA 02110-1301, USA.
20 */
21
22 #include "lxappearance.h"
23 #include "widget-theme.h"
24 #include "color-scheme.h"
25 #include <string.h>
26
27 static GSList* load_themes_in_dir(const char* theme_dir, GSList* themes)
28 {
29 GDir* dir = g_dir_open(theme_dir, 0, NULL);
30 if(dir)
31 {
32 const char* name;
33 while ((name = g_dir_read_name(dir)))
34 {
35 /* test if we already have this in list */
36 if(!g_slist_find_custom(themes, name, (GCompareFunc)strcmp))
37 {
38 /* test if this is a gtk theme */
39 char* gtkrc = g_build_filename(theme_dir, name, "gtk-2.0/gtkrc", NULL);
40 if(g_file_test(gtkrc, G_FILE_TEST_EXISTS))
41 themes = g_slist_prepend(themes, g_strdup(name));
42 g_free(gtkrc);
43 }
44 }
45 g_dir_close(dir);
46 }
47 return themes;
48 }
49
50 static void on_sel_changed(GtkTreeSelection* sel, gpointer user_data)
51 {
52 GtkTreeIter it;
53 GtkTreeModel* model;
54 if(gtk_tree_selection_get_selected(sel, &model, &it))
55 {
56 g_free(app.widget_theme);
57 gtk_tree_model_get(model, &it, 0, &app.widget_theme, -1);
58 g_object_set(gtk_settings_get_default(), "gtk-theme-name", app.widget_theme, NULL);
59 lxappearance_changed();
60
61 /* check if current theme support color schemes. */
62 color_scheme_update();
63 }
64 }
65
66 static void load_themes()
67 {
68 char* dir;
69 GSList* themes = NULL, *l;
70 GtkTreeIter sel_it = {0};
71 GtkTreeSelection* tree_sel;
72
73 /* load from userdata theme dir first */
74 dir = g_build_filename(g_get_user_data_dir(), "themes", NULL);
75 themes = load_themes_in_dir(dir, themes);
76 g_free(dir);
77
78 /* load from ~/.themes dir as old style */
79 dir = g_build_filename(g_get_home_dir(), ".themes", NULL);
80 themes = load_themes_in_dir(dir, themes);
81 g_free(dir);
82
83 /* load system default */
84 dir = gtk_rc_get_theme_dir();
85 themes = load_themes_in_dir(dir, themes);
86 g_free(dir);
87
88 themes = g_slist_sort(themes, (GCompareFunc)strcmp);
89 for(l = themes; l; l=l->next)
90 {
91 GtkTreeIter it;
92 char* name = (char*)l->data;
93 gtk_list_store_insert_with_values(app.widget_theme_store, &it, -1, 0, name, -1);
94 /* if this theme is the one currently in use */
95 if(!sel_it.user_data)
96 {
97 if(strcmp(name, app.widget_theme) == 0)
98 sel_it = it;
99 }
100 g_free(name);
101 }
102
103 gtk_tree_view_set_model(GTK_TREE_VIEW(app.widget_theme_view), GTK_TREE_MODEL(app.widget_theme_store));
104 tree_sel = gtk_tree_view_get_selection(GTK_TREE_VIEW(app.widget_theme_view));
105 if(sel_it.user_data)
106 {
107 GtkTreePath* tp = gtk_tree_model_get_path(GTK_TREE_MODEL(app.widget_theme_store), &sel_it);
108 gtk_tree_selection_select_iter(tree_sel, &sel_it);
109 gtk_tree_view_scroll_to_cell(GTK_TREE_VIEW(app.widget_theme_view), tp, NULL, FALSE, 0, 0);
110 gtk_tree_path_free(tp);
111 }
112
113 g_slist_free(themes);
114
115 g_signal_connect(tree_sel, "changed", G_CALLBACK(on_sel_changed), NULL);
116
117 /* FIXME: we need to handle this, too. */
118 // g_signal_connect(gtk_settings_get_default(), "notify::gtk-theme-name", G_CALLBACK(on_sel_changed), NULL);
119 }
120
121 static void on_font_set(GtkFontButton* btn, gpointer user_data)
122 {
123 const char* font_name = gtk_font_button_get_font_name(btn);
124 if(g_strcmp0(font_name, app.default_font))
125 {
126 g_free(app.default_font);
127 app.default_font = g_strdup(font_name);
128 g_object_set(gtk_settings_get_default(), "gtk-font-name", font_name, NULL);
129
130 lxappearance_changed();
131 }
132 }
133
134 void widget_theme_init(GtkBuilder* b)
135 {
136 GtkWidget* demo;
137 GtkWidget* demo_vbox;
138 GdkColor black = {0, 0, 0, 0};
139
140 demo = GTK_WIDGET(gtk_builder_get_object(b, "demo"));
141 demo_vbox = GTK_WIDGET(gtk_builder_get_object(b, "demo_vbox"));
142 app.widget_theme_view = GTK_WIDGET(gtk_builder_get_object(b, "widget_theme_view"));
143
144 gtk_widget_modify_bg(demo, GTK_STATE_NORMAL, &black);
145 #if GTK_CHECK_VERSION(3, 0, 0)
146 gtk_style_context_add_class (gtk_widget_get_style_context (demo_vbox), GTK_STYLE_CLASS_BACKGROUND);
147 #endif
148
149 app.widget_theme_store = gtk_list_store_new(1, G_TYPE_STRING);
150
151 /* load available themes */
152 load_themes();
153
154 app.default_font_btn = GTK_WIDGET(gtk_builder_get_object(b, "default_font"));
155 gtk_font_button_set_font_name(GTK_FONT_BUTTON(app.default_font_btn), app.default_font);
156 g_signal_connect(app.default_font_btn, "font-set", G_CALLBACK(on_font_set), NULL);
157 }