/* -*- linux-c -*- Copyright (C) 2004 Tom Szilagyi 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 of the License, 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. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id: skin.c 1086 2009-12-27 15:25:09Z peterszilagyi $ */ #include #include #include #include #include #include #include #include #include "common.h" #include "utils_gui.h" #include "gui_main.h" #include "playlist.h" #include "options.h" #include "i18n.h" #include "skin.h" extern options_t options; extern GtkWidget * main_window; char * pdir; GtkWidget * skin_window; GtkListStore * skin_store; GtkTreeSelection * skin_select; void apply_skin_foreach(GtkWidget * window) { gtk_widget_reset_rc_styles(window); gtk_widget_queue_draw(window); } void apply_skin(char * path) { char rcpath[MAXLEN]; sprintf(rcpath, "%s/rc", path); gtk_rc_parse(rcpath); toplevel_window_foreach(TOP_WIN_SKIN, apply_skin_foreach); main_buttons_set_content(path); playlist_set_color(); } static int filter(const struct dirent * de) { struct stat st_file; char dirname[MAXLEN]; if (de->d_name[0] == '.') { return 0; } snprintf(dirname, MAXLEN-1, "%s/%s", pdir, de->d_name); if (stat(dirname, &st_file) == -1) { fprintf(stderr, "error %s: skin.c/filter(): stat() failed on %s [likely cause: nonexistent file]\n", strerror(errno), dirname); return 0; } return S_ISDIR(st_file.st_mode); } static gint cancel(GtkWidget * widget, gpointer data) { gtk_widget_destroy(skin_window); return TRUE; } static gint apply(GtkWidget * widget, gpointer data) { GtkTreeModel * model; GtkTreeIter iter; char * str; if (gtk_tree_selection_get_selected(skin_select, &model, &iter)) { gtk_tree_model_get(model, &iter, 1, &str, -1); strcpy(options.skin, str); g_free(str); gtk_widget_destroy(skin_window); apply_skin(options.skin); } return TRUE; } static gint skin_window_key_pressed(GtkWidget * widget, GdkEventKey * kevent) { switch (kevent->keyval) { case GDK_q: case GDK_Q: case GDK_Escape: cancel(NULL, NULL); return TRUE; break; case GDK_Return: case GDK_KP_Enter: apply(NULL, NULL); return TRUE; break; } return FALSE; } static gint skin_list_double_click(GtkWidget * widget, GdkEventButton * event, gpointer func_data) { if ((event->type == GDK_2BUTTON_PRESS) && (event->button == 1)) { apply(NULL, NULL); return TRUE; } return FALSE; } void create_skin_window() { GtkWidget * vbox; GtkWidget * viewp; GtkWidget * scrolledwin; GtkWidget * skin_list; GtkTreeIter iter; GtkTreeViewColumn *column; GtkCellRenderer * renderer; GtkWidget * hbuttonbox; GtkWidget * apply_btn; GtkWidget * cancel_btn; struct dirent ** ent; int n; skin_window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_transient_for(GTK_WINDOW(skin_window), GTK_WINDOW(main_window)); gtk_widget_set_size_request(skin_window, 250, 240); gtk_window_set_title(GTK_WINDOW(skin_window), _("Skin chooser")); gtk_window_set_position(GTK_WINDOW(skin_window), GTK_WIN_POS_CENTER); gtk_window_set_modal(GTK_WINDOW(skin_window), TRUE); gtk_container_set_border_width(GTK_CONTAINER(skin_window), 2); g_signal_connect(G_OBJECT(skin_window), "key_press_event", G_CALLBACK(skin_window_key_pressed), NULL); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(skin_window), vbox); viewp = gtk_viewport_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(vbox), viewp, TRUE, TRUE, 0); scrolledwin = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); gtk_container_add(GTK_CONTAINER(viewp), scrolledwin); skin_store = gtk_list_store_new(2, G_TYPE_STRING, /* skin name */ G_TYPE_STRING); /* path */ skin_list = gtk_tree_view_new_with_model(GTK_TREE_MODEL(skin_store)); gtk_tree_view_set_enable_search(GTK_TREE_VIEW(skin_list), FALSE); g_signal_connect(G_OBJECT(skin_list), "button_press_event", G_CALLBACK(skin_list_double_click), NULL); skin_select = gtk_tree_view_get_selection(GTK_TREE_VIEW(skin_list)); renderer = gtk_cell_renderer_text_new(); column = gtk_tree_view_column_new_with_attributes(_("Available skins"), renderer, "text", 0, NULL); gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(skin_store), 0, GTK_SORT_ASCENDING); gtk_tree_view_append_column(GTK_TREE_VIEW(skin_list), column); gtk_container_add(GTK_CONTAINER(scrolledwin), skin_list); /* per-user skins */ pdir = options.confdir; n = scandir(options.confdir, &ent, filter, alphasort); if (n >= 0) { int c; char path[MAXLEN]; for (c = 0; c < n; ++c) { gtk_list_store_append(skin_store, &iter); snprintf(path, MAXLEN - 1, "%s/%s", options.confdir, ent[c]->d_name); gtk_list_store_set(skin_store, &iter, 0, ent[c]->d_name, 1, path, -1); free(ent[c]); } free(ent); } /* system wide skins */ pdir = AQUALUNG_SKINDIR; n = scandir(AQUALUNG_SKINDIR, &ent, filter, alphasort); if (n >= 0) { int c; char path[MAXLEN]; for (c = 0; c < n; ++c) { int found = 0; if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(skin_store), &iter)) { int i = 0; char * str; do { gtk_tree_model_get(GTK_TREE_MODEL(skin_store), &iter, 0, &str, -1); if (strcmp(str, ent[c]->d_name) == 0) { found = 1; } g_free(str); } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(skin_store), &iter)); } if (!found) { if (strncmp(ent[c]->d_name, "no_skin", MAXLEN-1)) { gtk_list_store_append(skin_store, &iter); snprintf(path, MAXLEN - 1, "%s/%s", AQUALUNG_SKINDIR, ent[c]->d_name); gtk_list_store_set(skin_store, &iter, 0, ent[c]->d_name, 1, path, -1); } } free(ent[c]); } free(ent); } hbuttonbox = gtk_hbutton_box_new(); gtk_box_pack_end(GTK_BOX(vbox), hbuttonbox, FALSE, TRUE, 0); gtk_button_box_set_layout(GTK_BUTTON_BOX(hbuttonbox), GTK_BUTTONBOX_END); gtk_box_set_spacing(GTK_BOX(hbuttonbox), 8); gtk_container_set_border_width(GTK_CONTAINER(hbuttonbox), 3); apply_btn = gtk_button_new_from_stock (GTK_STOCK_APPLY); g_signal_connect(apply_btn, "clicked", G_CALLBACK(apply), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), apply_btn); cancel_btn = gtk_button_new_from_stock (GTK_STOCK_CANCEL); g_signal_connect(cancel_btn, "clicked", G_CALLBACK(cancel), NULL); gtk_container_add(GTK_CONTAINER(hbuttonbox), cancel_btn); gtk_widget_show_all(skin_window); if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(skin_store), &iter)) { int i = 0; char * str; do { gtk_tree_model_get(GTK_TREE_MODEL(skin_store), &iter, 1, &str, -1); if (strcmp(str, options.skin) == 0) { gtk_tree_selection_select_iter(skin_select, &iter); gtk_tree_view_set_cursor(GTK_TREE_VIEW(skin_list), gtk_tree_model_get_path(GTK_TREE_MODEL(skin_store), &iter), NULL, FALSE); } g_free(str); } while (i++, gtk_tree_model_iter_next(GTK_TREE_MODEL(skin_store), &iter)); } } // vim: shiftwidth=8:tabstop=8:softtabstop=8 :