build: Use .ONESHELL.
[paraslash.git] / gui_theme.c
1 /* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
2
3 /** \file gui_theme.c Theme definitions. */
4
5 #include "para.h"
6 #include "gui.h"
7 #include <curses.h>
8
9 static void init_theme_simple(struct gui_theme *t)
10 {
11 struct stat_item_data *d = t->data;
12 t->author = "Andre Noll";
13 t->lines_min = 5;
14 t->top_lines_min = 2;
15 t->cols_min = 40;
16 t->top_lines_default = 2;
17 t->sb.bg = COLOR_CYAN;
18 t->sb.fg = COLOR_BLACK;
19 t->cmd.bg = COLOR_WHITE;
20 t->cmd.fg = COLOR_BLACK;
21 t->output.bg = COLOR_BLUE;
22 t->output.fg = COLOR_WHITE;
23 t->msg.bg = COLOR_BLUE;
24 t->msg.fg = COLOR_YELLOW;
25 t->err_msg.bg = COLOR_RED;
26 t->err_msg.fg = COLOR_WHITE;
27 t->sep.bg = COLOR_BLUE;
28 t->sep.fg = COLOR_CYAN;
29 t->dflt.fg = COLOR_WHITE;
30 t->dflt.bg = COLOR_BLUE;
31 t->sep_char = '*';
32
33 d[SI_basename].prefix = "";
34 d[SI_basename].postfix = "";
35 d[SI_basename].color.fg = COLOR_WHITE;
36 d[SI_basename].color.bg = COLOR_BLUE;
37 d[SI_basename].align = CENTER;
38 d[SI_basename].x = 0;
39 d[SI_basename].y = 7;
40 d[SI_basename].len = 100;
41
42 d[SI_status].prefix = "para_server: ";
43 d[SI_status].postfix = "";
44 d[SI_status].color.fg = COLOR_WHITE;
45 d[SI_status].color.bg = COLOR_BLUE;
46 d[SI_status].align = CENTER;
47 d[SI_status].x = 0;
48 d[SI_status].y = 60;
49 d[SI_status].len = 50;
50
51 d[SI_audiod_status].prefix = "para_audiod: ";
52 d[SI_audiod_status].postfix = "";
53 d[SI_audiod_status].color.fg = COLOR_WHITE;
54 d[SI_audiod_status].color.bg = COLOR_BLUE;
55 d[SI_audiod_status].align = CENTER;
56 d[SI_audiod_status].x = 50;
57 d[SI_audiod_status].y = 60;
58 d[SI_audiod_status].len = 50;
59
60 }
61
62 static void init_theme_colorful_blackness(struct gui_theme *t)
63 {
64 struct stat_item_data *d = t->data;
65 t->author = "Andre Noll";
66 /* minimal number of lines that is needed to display all
67 * information provided by this theme
68 */
69 t->lines_min = 15;
70 t->cols_min = 80;
71 t->top_lines_min = 9;
72 t->top_lines_default = 11; /* default number of lines */
73
74 t->sb.bg = COLOR_GREEN; /* status bar background */
75 t->sb.fg = COLOR_BLACK; /* status bar foreground */
76 t->cmd.bg = COLOR_BLACK;
77 t->cmd.fg = COLOR_YELLOW;
78 t->output.bg = COLOR_BLACK;
79 t->output.fg = COLOR_CYAN;
80 t->msg.bg = COLOR_BLACK;
81 t->msg.fg = COLOR_WHITE;
82 t->err_msg.bg = COLOR_RED;
83 t->err_msg.fg = COLOR_WHITE;
84 t->sep.bg = COLOR_BLACK; /* color of the separator */
85 t->sep.fg = COLOR_BLUE;
86 t->sep_char = 0; /* default (ACS_HLINE) */
87 t->dflt.bg = COLOR_BLACK;
88 t->dflt.fg = COLOR_MAGENTA;
89
90
91 d[SI_play_time].prefix = "";
92 d[SI_play_time].postfix = "";
93 d[SI_play_time].color.fg = COLOR_CYAN;
94 d[SI_play_time].color.bg = COLOR_BLACK;
95 d[SI_play_time].align = CENTER;
96 d[SI_play_time].x = 0;
97 d[SI_play_time].y = 7;
98 d[SI_play_time].len = 35;
99
100 d[SI_basename].prefix = "";
101 d[SI_basename].postfix = "";
102 d[SI_basename].color.fg = COLOR_CYAN;
103 d[SI_basename].color.bg = COLOR_BLACK;
104 d[SI_basename].align = LEFT;
105 d[SI_basename].x = 35;
106 d[SI_basename].y = 7;
107 d[SI_basename].len = 65;
108
109 d[SI_status].prefix = "";
110 d[SI_status].postfix = " ";
111 d[SI_status].color.fg = COLOR_RED;
112 d[SI_status].color.bg = COLOR_BLACK;
113 d[SI_status].align = RIGHT;
114 d[SI_status].x = 0;
115 d[SI_status].y = 17;
116 d[SI_status].len = 11;
117
118 d[SI_status_flags].prefix = "(";
119 d[SI_status_flags].postfix = ")";
120 d[SI_status_flags].color.fg = COLOR_RED;
121 d[SI_status_flags].color.bg = COLOR_BLACK;
122 d[SI_status_flags].align = LEFT;
123 d[SI_status_flags].x = 11;
124 d[SI_status_flags].y = 17;
125 d[SI_status_flags].len = 10;
126
127 d[SI_image_id].prefix = "img: ";
128 d[SI_image_id].postfix = "";
129 d[SI_image_id].color.fg = COLOR_RED;
130 d[SI_image_id].color.bg = COLOR_BLACK;
131 d[SI_image_id].align = CENTER;
132 d[SI_image_id].x = 21;
133 d[SI_image_id].y = 17;
134 d[SI_image_id].len = 10;
135
136 d[SI_lyrics_id].prefix = "lyr: ";
137 d[SI_lyrics_id].postfix = "";
138 d[SI_lyrics_id].color.fg = COLOR_RED;
139 d[SI_lyrics_id].color.bg = COLOR_BLACK;
140 d[SI_lyrics_id].align = CENTER;
141 d[SI_lyrics_id].x = 31;
142 d[SI_lyrics_id].y = 17;
143 d[SI_lyrics_id].len = 11;
144
145 d[SI_format].prefix = "format: ";
146 d[SI_format].postfix = "";
147 d[SI_format].color.fg = COLOR_RED;
148 d[SI_format].color.bg = COLOR_BLACK;
149 d[SI_format].align = CENTER;
150 d[SI_format].x = 42;
151 d[SI_format].y = 17;
152 d[SI_format].len = 18;
153
154 d[SI_num_played].prefix = "#";
155 d[SI_num_played].postfix = "";
156 d[SI_num_played].color.fg = COLOR_RED;
157 d[SI_num_played].color.bg = COLOR_BLACK;
158 d[SI_num_played].align = LEFT;
159 d[SI_num_played].x = 60;
160 d[SI_num_played].y = 17;
161 d[SI_num_played].len = 5;
162
163 d[SI_bitrate].prefix = "";
164 d[SI_bitrate].postfix = "";
165 d[SI_bitrate].color.fg = COLOR_RED;
166 d[SI_bitrate].color.bg = COLOR_BLACK;
167 d[SI_bitrate].align = CENTER;
168 d[SI_bitrate].x = 65;
169 d[SI_bitrate].y = 17;
170 d[SI_bitrate].len = 13;
171
172 d[SI_frequency].prefix = "";
173 d[SI_frequency].postfix = "";
174 d[SI_frequency].color.fg = COLOR_RED;
175 d[SI_frequency].color.bg = COLOR_BLACK;
176 d[SI_frequency].align = CENTER;
177 d[SI_frequency].x = 78;
178 d[SI_frequency].y = 17;
179 d[SI_frequency].len = 10;
180
181 d[SI_score].prefix = "sc: ";
182 d[SI_score].postfix = "";
183 d[SI_score].color.fg = COLOR_RED;
184 d[SI_score].color.bg = COLOR_BLACK;
185 d[SI_score].align = CENTER;
186 d[SI_score].x = 88;
187 d[SI_score].y = 17;
188 d[SI_score].len = 10;
189
190 d[SI_audiod_status].prefix = "";
191 d[SI_audiod_status].postfix = "";
192 d[SI_audiod_status].color.fg = COLOR_MAGENTA;
193 d[SI_audiod_status].color.bg = COLOR_BLACK;
194 d[SI_audiod_status].align = CENTER;
195 d[SI_audiod_status].x = 0;
196 d[SI_audiod_status].y = 27;
197 d[SI_audiod_status].len = 5;
198
199 d[SI_decoder_flags].prefix = "[";
200 d[SI_decoder_flags].postfix = "]";
201 d[SI_decoder_flags].color.fg = COLOR_MAGENTA;
202 d[SI_decoder_flags].color.bg = COLOR_BLACK;
203 d[SI_decoder_flags].align = CENTER;
204 d[SI_decoder_flags].x = 5;
205 d[SI_decoder_flags].y = 27;
206 d[SI_decoder_flags].len = 10;
207
208 d[SI_mtime].prefix = "mod: ";
209 d[SI_mtime].postfix = "";
210 d[SI_mtime].color.fg = COLOR_MAGENTA;
211 d[SI_mtime].color.bg = COLOR_BLACK;
212 d[SI_mtime].align = CENTER;
213 d[SI_mtime].x = 15;
214 d[SI_mtime].y = 27;
215 d[SI_mtime].len = 22;
216
217 d[SI_file_size].prefix = "";
218 d[SI_file_size].postfix = "kb";
219 d[SI_file_size].color.fg = COLOR_MAGENTA;
220 d[SI_file_size].color.bg = COLOR_BLACK;
221 d[SI_file_size].align = CENTER;
222 d[SI_file_size].x = 37;
223 d[SI_file_size].y = 27;
224 d[SI_file_size].len = 10;
225
226 d[SI_channels].prefix = "";
227 d[SI_channels].postfix = "ch";
228 d[SI_channels].color.fg = COLOR_MAGENTA;
229 d[SI_channels].color.bg = COLOR_BLACK;
230 d[SI_channels].align = CENTER;
231 d[SI_channels].x = 47;
232 d[SI_channels].y = 27;
233 d[SI_channels].len = 5;
234
235 d[SI_last_played].prefix = "lp: ";
236 d[SI_last_played].postfix = "";
237 d[SI_last_played].color.fg = COLOR_MAGENTA;
238 d[SI_last_played].color.bg = COLOR_BLACK;
239 d[SI_last_played].align = CENTER;
240 d[SI_last_played].x = 52;
241 d[SI_last_played].y = 27;
242 d[SI_last_played].len = 21;
243
244 d[SI_num_chunks].prefix = "";
245 d[SI_num_chunks].postfix = "x";
246 d[SI_num_chunks].color.fg = COLOR_MAGENTA;
247 d[SI_num_chunks].color.bg = COLOR_BLACK;
248 d[SI_num_chunks].align = RIGHT;
249 d[SI_num_chunks].x = 73;
250 d[SI_num_chunks].y = 27;
251 d[SI_num_chunks].len = 11;
252
253 d[SI_chunk_time].prefix = "";
254 d[SI_chunk_time].postfix = "ms";
255 d[SI_chunk_time].color.fg = COLOR_MAGENTA;
256 d[SI_chunk_time].color.bg = COLOR_BLACK;
257 d[SI_chunk_time].align = LEFT;
258 d[SI_chunk_time].x = 84;
259 d[SI_chunk_time].y = 27;
260 d[SI_chunk_time].len = 8;
261
262 d[SI_amplification].prefix = "amp:";
263 d[SI_amplification].postfix = "";
264 d[SI_amplification].color.fg = COLOR_MAGENTA;
265 d[SI_amplification].color.bg = COLOR_BLACK;
266 d[SI_amplification].align = RIGHT;
267 d[SI_amplification].x = 92;
268 d[SI_amplification].y = 27;
269 d[SI_amplification].len = 8;
270
271 d[SI_techinfo].prefix = "";
272 d[SI_techinfo].postfix = "";
273 d[SI_techinfo].color.fg = COLOR_GREEN;
274 d[SI_techinfo].color.bg = COLOR_BLACK;
275 d[SI_techinfo].align = CENTER;
276 d[SI_techinfo].x = 0;
277 d[SI_techinfo].y = 43;
278 d[SI_techinfo].len = 100;
279
280 d[SI_title].prefix = "";
281 d[SI_title].postfix = ",";
282 d[SI_title].color.fg = COLOR_GREEN;
283 d[SI_title].color.bg = COLOR_BLACK;
284 d[SI_title].align = RIGHT;
285 d[SI_title].x = 0;
286 d[SI_title].y = 53;
287 d[SI_title].len = 45;
288
289 d[SI_artist].prefix = " by ";
290 d[SI_artist].postfix = "";
291 d[SI_artist].color.fg = COLOR_GREEN;
292 d[SI_artist].color.bg = COLOR_BLACK;
293 d[SI_artist].align = LEFT;
294 d[SI_artist].x = 45;
295 d[SI_artist].y = 53;
296 d[SI_artist].len = 45;
297
298 d[SI_year].prefix = "(";
299 d[SI_year].postfix = ")";
300 d[SI_year].color.fg = COLOR_GREEN;
301 d[SI_year].color.bg = COLOR_BLACK;
302 d[SI_year].align = RIGHT;
303 d[SI_year].x = 90;
304 d[SI_year].y = 53;
305 d[SI_year].len = 10;
306
307 d[SI_album].prefix = "A: ";
308 d[SI_album].postfix = ",";
309 d[SI_album].color.fg = COLOR_GREEN;
310 d[SI_album].color.bg = COLOR_BLACK;
311 d[SI_album].align = RIGHT;
312 d[SI_album].x = 0;
313 d[SI_album].y = 63;
314 d[SI_album].len = 50;
315
316 d[SI_comment].prefix = " C: ";
317 d[SI_comment].postfix = "";
318 d[SI_comment].color.fg = COLOR_GREEN;
319 d[SI_comment].color.bg = COLOR_BLACK;
320 d[SI_comment].align = LEFT;
321 d[SI_comment].x = 50;
322 d[SI_comment].y = 63;
323 d[SI_comment].len = 50;
324
325 d[SI_afs_mode].prefix = "";
326 d[SI_afs_mode].postfix = "";
327 d[SI_afs_mode].color.fg = COLOR_YELLOW;
328 d[SI_afs_mode].color.bg = COLOR_BLACK;
329 d[SI_afs_mode].align = CENTER;
330 d[SI_afs_mode].x = 0;
331 d[SI_afs_mode].y = 77;
332 d[SI_afs_mode].len = 100;
333
334 d[SI_attributes_txt].prefix = "";
335 d[SI_attributes_txt].postfix = "";
336 d[SI_attributes_txt].color.fg = COLOR_YELLOW;
337 d[SI_attributes_txt].color.bg = COLOR_BLACK;
338 d[SI_attributes_txt].align = CENTER;
339 d[SI_attributes_txt].x = 0;
340 d[SI_attributes_txt].y = 87;
341 d[SI_attributes_txt].len = 100;
342
343 d[SI_directory].prefix = "dir: ";
344 d[SI_directory].postfix = "";
345 d[SI_directory].color.fg = COLOR_YELLOW;
346 d[SI_directory].color.bg = COLOR_BLACK;
347 d[SI_directory].align = CENTER;
348 d[SI_directory].x = 0;
349 d[SI_directory].y = 97;
350 d[SI_directory].len = 100;
351 }
352
353 struct theme_description {
354 const char *name;
355 void (*init)(struct gui_theme *t);
356 };
357
358 static struct theme_description themes[] = {
359 {
360 .name = "colorful blackness",
361 .init = init_theme_colorful_blackness,
362 },
363 {
364 .name = "simple",
365 .init = init_theme_simple,
366 },
367 };
368
369 /** Number of elements in the \a themes array. */
370 #define NUM_THEMES (ARRAY_SIZE(themes))
371
372 static int current_theme_num;
373
374 static void set_theme(int num, struct gui_theme *t)
375 {
376 int i;
377 FOR_EACH_STATUS_ITEM(i)
378 t->data[i].len = 0;
379 num %= NUM_THEMES;
380 t->name = themes[num].name;
381 themes[num].init(t);
382 current_theme_num = num;
383 PARA_NOTICE_LOG("theme: %s\n", t->name);
384 }
385
386 /**
387 * Initialize a theme.
388 *
389 * \param name Name of the theme to be initialized.
390 * \param t The function fills out this structure.
391 *
392 * This function exits if there is no theme called \a name.
393 */
394 void theme_init(const char *name, struct gui_theme *t)
395 {
396 int i;
397
398 if (!name)
399 return set_theme(0, t);
400 for (i = 0; i < NUM_THEMES; i++)
401 if (strcmp(name, themes[i].name) == 0)
402 return set_theme(i, t);
403 fprintf(stderr, "Available themes:\n");
404 for (i = 0; i < NUM_THEMES; i++)
405 fprintf(stderr, "\t%s\n", themes[i].name);
406 exit(EXIT_FAILURE);
407 }
408
409 /**
410 * Activate the previous available theme.
411 *
412 * \param t Theme definition is stored here.
413 *
414 * This picks the theme that comes before the currently active one, or the last
415 * available theme, if the current one is the first.
416 *
417 * \sa \ref theme_next().
418 */
419 void theme_prev(struct gui_theme *t)
420 {
421 return set_theme(++current_theme_num, t);
422 }
423
424 /**
425 * Activate the next available theme.
426 *
427 * \param t Theme definition is stored here.
428 *
429 * This works exactly as theme_prev() but cycles forwards through the list of
430 * available themes.
431 */
432 void theme_next(struct gui_theme *t)
433 {
434 return set_theme(--current_theme_num, t);
435 }