clean up appearance code
[dana/obconf.git] / src / appearance.c
1 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*-
2
3    appearance.c for ObConf, the configuration tool for Openbox
4    Copyright (c) 2003-2007   Dana Jansens
5    Copyright (c) 2003        Tim Riley
6
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; either version 2 of the License, or
10    (at your option) any later version.
11
12    This program is distributed in the hope that it will be useful,
13    but WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15    GNU General Public License for more details.
16
17    See the COPYING file for a copy of the GNU General Public License.
18 */
19
20 #include "main.h"
21 #include "tree.h"
22 #include "preview_update.h"
23
24 static gboolean mapping = FALSE;
25
26 static RrFont *read_font(GtkFontButton *w, const gchar *place);
27 static RrFont *write_font(GtkFontButton *w, const gchar *place);
28
29 void appearance_setup_tab()
30 {
31     GtkWidget *w;
32     gchar *layout;
33     RrFont *f;
34
35     mapping = TRUE;
36
37     w = get_widget("window_border");
38     gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(w),
39                                  tree_get_bool("theme/keepBorder", TRUE));
40
41     w = get_widget("title_layout");
42     layout = tree_get_string("theme/titleLayout", "NLIMC");
43     gtk_entry_set_text(GTK_ENTRY(w), layout);
44     preview_update_set_title_layout(layout);
45     g_free(layout);
46
47     w = get_widget("font_active");
48     f = read_font(GTK_FONT_BUTTON(w), "ActiveWindow");
49     preview_update_set_active_font(f);
50
51     w = get_widget("font_inactive");
52     f = read_font(GTK_FONT_BUTTON(w), "InactiveWindow");
53     preview_update_set_inactive_font(f);
54
55     w = get_widget("font_menu_header");
56     f = read_font(GTK_FONT_BUTTON(w), "MenuHeader");
57     preview_update_set_menu_header_font(f);
58
59     w = get_widget("font_menu_item");
60     f = read_font(GTK_FONT_BUTTON(w), "MenuItem");
61     preview_update_set_menu_item_font(f);
62
63     w = get_widget("font_display");
64     f = read_font(GTK_FONT_BUTTON(w), "OnScreenDisplay");
65     preview_update_set_osd_font(f);
66
67     mapping = FALSE;
68 }
69
70 void on_window_border_toggled(GtkToggleButton *w, gpointer data)
71 {
72     gboolean b;
73
74     if (mapping) return;
75
76     b = gtk_toggle_button_get_active(w);
77     tree_set_bool("theme/keepBorder", b);
78 }
79
80 void on_title_layout_changed(GtkEntry *w, gpointer data)
81 {
82     gchar *layout;
83     gchar *it, *it2;
84     gboolean n, d, s, l, i, m, c;
85
86     if (mapping) return;
87
88     layout = g_strdup(gtk_entry_get_text(w));
89
90     n = d = s = l = i = m = c = FALSE;
91
92     for (it = layout; *it; ++it) {
93         gboolean *b;
94
95         switch (*it) {
96         case 'N':
97         case 'n':
98             b = &n;
99             break;
100         case 'd':
101         case 'D':
102             b = &d;
103             break;
104         case 's':
105         case 'S':
106             b = &s;
107             break;
108         case 'l':
109         case 'L':
110             b = &l;
111             break;
112         case 'i':
113         case 'I':
114             b = &i;
115             break;
116         case 'm':
117         case 'M':
118             b = &m;
119             break;
120         case 'c':
121         case 'C':
122             b = &c;
123             break;
124         default:
125             b = NULL;
126             break;
127         }
128
129         if (!b || *b) {
130             /* drop the letter */
131             for (it2 = it; *it2; ++it2)
132                 *it2 = *(it2+1);
133         } else {
134             *it = toupper(*it);
135             *b = TRUE;
136         }
137     }
138
139     gtk_entry_set_text(w, layout);
140     tree_set_string("theme/titleLayout", layout);
141     preview_update_set_title_layout(layout);
142
143     g_free(layout);
144 }
145
146 void on_font_active_font_set(GtkFontButton *w, gpointer data)
147 {
148     preview_update_set_active_font(write_font(w, "ActiveWindow"));
149 }
150
151 void on_font_inactive_font_set(GtkFontButton *w, gpointer data)
152 {
153     preview_update_set_inactive_font(write_font(w, "InactiveWindow"));
154 }
155
156 void on_font_menu_header_font_set(GtkFontButton *w, gpointer data)
157 {
158     preview_update_set_menu_header_font(write_font(w, "MenuHeader"));
159 }
160
161 void on_font_menu_item_font_set(GtkFontButton *w, gpointer data)
162 {
163     preview_update_set_menu_item_font(write_font(w, "MenuItem"));
164 }
165
166 void on_font_display_font_set(GtkFontButton *w, gpointer data)
167 {
168     preview_update_set_osd_font(write_font(w, "OnScreenDisplay"));
169 }
170
171 static RrFont *read_font(GtkFontButton *w, const gchar *place)
172 {
173     RrFont *font;
174     gchar *fontstring, *node;
175     gchar *name, **names;
176     gchar *size;
177     gchar *weight;
178     gchar *slant;
179
180     RrFontWeight rr_weight = RR_FONTWEIGHT_NORMAL;
181     RrFontSlant rr_slant = RR_FONTSLANT_NORMAL;
182
183     mapping = TRUE;
184
185     node = g_strdup_printf("theme/font:place=%s/name", place);
186     name = tree_get_string(node, "Sans");
187     g_free(node);
188
189     node = g_strdup_printf("theme/font:place=%s/size", place);
190     size = tree_get_string(node, "8");
191     g_free(node);
192
193     node = g_strdup_printf("theme/font:place=%s/weight", place);
194     weight = tree_get_string(node, "");
195     g_free(node);
196
197     node = g_strdup_printf("theme/font:place=%s/slant", place);
198     slant = tree_get_string(node, "");
199     g_free(node);
200
201     /* get only the first font in the string */
202     names = g_strsplit(name, ",", 0);
203     g_free(name);
204     name = g_strdup(names[0]);
205     g_strfreev(names);
206
207     /* don't use "normal" in the gtk string */
208     if (!g_ascii_strcasecmp(weight, "normal")) {
209         g_free(weight); weight = g_strdup("");
210     }
211     if (!g_ascii_strcasecmp(slant, "normal")) {
212         g_free(slant); slant = g_strdup("");
213     }
214
215     fontstring = g_strdup_printf("%s %s %s %s", name, weight, slant, size);
216     gtk_font_button_set_font_name(w, fontstring);
217
218     if (!g_ascii_strcasecmp(weight, "Bold")) rr_weight = RR_FONTWEIGHT_BOLD;
219     if (!g_ascii_strcasecmp(slant, "Italic")) rr_slant = RR_FONTSLANT_ITALIC;
220     if (!g_ascii_strcasecmp(slant, "Oblique")) rr_slant = RR_FONTSLANT_OBLIQUE;
221
222     font = RrFontOpen(rrinst, name, atoi(size), rr_weight, rr_slant);
223     g_free(fontstring);
224     g_free(slant);
225     g_free(weight);
226     g_free(size);
227     g_free(name);
228
229     mapping = FALSE;
230
231     return font;
232 }
233
234 static RrFont *write_font(GtkFontButton *w, const gchar *place)
235 {
236     gchar *c;
237     gchar *font, *node;
238     const gchar *size = NULL;
239     const gchar *bold = NULL;
240     const gchar *italic = NULL;
241
242     RrFontWeight weight = RR_FONTWEIGHT_NORMAL;
243     RrFontSlant slant = RR_FONTSLANT_NORMAL;
244
245     if (mapping) return;
246
247     font = g_strdup(gtk_font_button_get_font_name(w));
248     while ((c = strrchr(font, ' '))) {
249         if (!bold && !italic && !size && atoi(c+1))
250             size = c+1;
251         else if (!bold && !italic && !g_ascii_strcasecmp(c+1, "italic"))
252             italic = c+1;
253         else if (!bold && !g_ascii_strcasecmp(c+1, "bold"))
254             bold = c+1;
255         else
256             break;
257         *c = '\0';
258     }
259     if (!bold) bold = "Normal";
260     if (!italic) italic = "Normal";
261
262     node = g_strdup_printf("theme/font:place=%s/name", place);
263     tree_set_string(node, font);
264     g_free(node);
265
266     node = g_strdup_printf("theme/font:place=%s/size", place);
267     tree_set_string(node, size);
268     g_free(node);
269
270     node = g_strdup_printf("theme/font:place=%s/weight", place);
271     tree_set_string(node, bold);
272     g_free(node);
273
274     node = g_strdup_printf("theme/font:place=%s/slant", place);
275     tree_set_string(node, italic);
276     g_free(node);
277
278     if (!g_ascii_strcasecmp(bold, "Bold")) weight = RR_FONTWEIGHT_BOLD;
279     if (!g_ascii_strcasecmp(italic, "Italic")) slant = RR_FONTSLANT_ITALIC;
280     if (!g_ascii_strcasecmp(italic, "Oblique")) slant = RR_FONTSLANT_OBLIQUE;
281
282     return RrFontOpen(rrinst, font, atoi(size), weight, slant);
283
284     g_free(font);
285
286 }