#include #include #include #include #include #include #include #include #include #include #include "gdancer.h" #include "gui.h" typedef struct { GtkAdjustment *adjustment; GtkWidget *window; GtkWidget *vbox; GtkWidget *label; GtkWidget *close_button; } GlobalConfig; void save_global_config (void) { ConfigFile *cfg; gchar *filename = NULL; filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); cfg = xmms_cfg_open_file(filename); if (!cfg) cfg = xmms_cfg_new(); // Save global config options here xmms_cfg_write_file(cfg, filename); xmms_cfg_free(cfg); g_free (filename); } void load_global_config (void) { ConfigFile *cfg; gchar *filename = NULL; filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); cfg = xmms_cfg_open_file (filename); if (!cfg) cfg = xmms_cfg_new(); // load global config options here xmms_cfg_free (cfg); g_free (filename); } void global_config_close (GtkWidget *widget, GlobalConfig *global) { // Close the global config window gtk_widget_destroy (global->label); gtk_widget_destroy (global->close_button); gtk_widget_destroy (global->vbox); gtk_widget_destroy (global->window); g_free (global); save_global_config(); } void global_config (void) { // This is the global config which effects all dancers GlobalConfig *global = NULL; global = g_malloc0 (sizeof(GlobalConfig)); load_global_config (); global->window = gtk_window_new(GTK_WINDOW_DIALOG); global->vbox = gtk_vbox_new (FALSE, 3); global->label = gtk_label_new ("This is the Global Configuration\nWindow. Settings here effect all\nof the dancers.\nHowever, there are no global\nconfig options at this time.\n\nNOTE: Right Click on a dancer for\ndancer-specific menu."); global->close_button = gtk_button_new_with_label ("Close"); gtk_signal_connect (GTK_OBJECT(global->close_button), "clicked", GTK_SIGNAL_FUNC(global_config_close), global); gtk_container_add (GTK_CONTAINER(global->window), global->vbox); gtk_box_pack_start (GTK_BOX(global->vbox), global->label, FALSE, FALSE, 3); gtk_box_pack_start (GTK_BOX(global->vbox), global->close_button, FALSE, FALSE, 3); gtk_widget_show (global->label); gtk_widget_show (global->close_button); gtk_widget_show (global->vbox); gtk_widget_show (global->window); } void gd_make_dancers (void) { // make new dancers by reading config file ConfigFile *cfg = NULL; gchar *filename = NULL; gchar *theme_dir = NULL; gint dancers = 0; gint i = 0; theme_dir = g_strconcat (g_get_home_dir(), "/.xmms/gdancer_themes/", NULL); mkdir (theme_dir, 0755); g_free (theme_dir); filename = g_strconcat (g_get_home_dir(), "/.xmms/config", NULL); cfg = xmms_cfg_open_file (filename); g_free (filename); if (!cfg) { gd_get_new_dancer(); return; } if (!xmms_cfg_read_int(cfg, PROGNAME, "dancers", &dancers)) { gd_get_new_dancer(); xmms_cfg_free(cfg); return; } else if (dancers == 0) { gd_get_new_dancer(); xmms_cfg_free (cfg); return; } for (i = 0; i < dancers; i++) { GDancer *dancer = NULL; gchar name[15]; gchar *theme = NULL; //set name to use g_snprintf(name, 14, "theme%d", i); if (!xmms_cfg_read_string(cfg, PROGNAME, name, &theme)) { printf ("Couldn't get theme name for %s\n", name); gd_get_new_dancer(); xmms_cfg_free(cfg); return; } dancer = gd_get_new_dancer_with_theme (theme); g_free(theme); g_snprintf(name, 14, "x%d", i); xmms_cfg_read_int(cfg, PROGNAME, name, &(dancer->x)); g_snprintf(name, 14, "y%d", i); xmms_cfg_read_int(cfg, PROGNAME, name, &(dancer->y)); g_snprintf(name, 14, "move_dancer%d", i); if (!xmms_cfg_read_boolean(cfg, PROGNAME, name, &(dancer->move_dancer))) { dancer->move_dancer = 0; } g_snprintf(name, 14, "skip_frames%d", i); if (!xmms_cfg_read_int(cfg, PROGNAME, name, &(dancer->skip_frames))) { dancer->skip_frames = 3; } gd_move_window (dancer); } xmms_cfg_free(cfg); } void gd_save_config (void) { // Save configuration for a dancer ConfigFile *cfg; gchar *filename = NULL; gint i = 0; filename = g_strconcat(g_get_home_dir(), "/.xmms/config", NULL); cfg = xmms_cfg_open_file(filename); if (!cfg) cfg = xmms_cfg_new(); xmms_cfg_write_int(cfg, PROGNAME, "dancers", g_list_length (gdancers)); for (i = 0; i < g_list_length(gdancers);i++) { gchar name[15]; GDancer *dancer = NULL; // get dancer information dancer = g_list_nth_data (gdancers, i); // set name to use when writing theme g_snprintf (name, 14, "theme%d", i); xmms_cfg_write_string(cfg, PROGNAME, name, dancer->theme); // set name to use when writing x coord g_snprintf (name, 14, "x%d", i); xmms_cfg_write_int(cfg, PROGNAME, name, dancer->x); // set name to use when writing y coord g_snprintf (name, 14, "y%d", i); xmms_cfg_write_int(cfg, PROGNAME, name, dancer->y); // set name to use when writing move_dancer g_snprintf (name, 14, "move_dancer%d", i); xmms_cfg_write_boolean(cfg, PROGNAME, name, dancer->move_dancer); // set name to use when writing skip_frames g_snprintf (name, 14, "skip_frames%d", i); xmms_cfg_write_int(cfg, PROGNAME, name, dancer->skip_frames); } xmms_cfg_write_file(cfg, filename); xmms_cfg_free(cfg); g_free(filename); } // sort function, used below gint sort_alpha (gconstpointer a, gconstpointer b) { char *c = a; char *d = b; // compare the first character of each while (*c == *d && *c != 0 && *d != 0) { c++; d++; } if (*c < *d) return -1; else if (*c > *d) return 1; else return 0; } void config_themes_list (GtkWidget *widget, GDancer *dancer) { // Code to list the themes in the themes directory. // This code is from xmms_speakers, only with minor changes GList *themeslist = NULL; DIR *directory; struct dirent *file; struct stat buffer; gchar *dirname; gint i; // set directory to ~/.xmms/gdancer_themes/ dirname = g_strconcat(g_get_home_dir(), "/.xmms/gdancer_themes/",NULL); // Append the default theme to themes list themeslist = g_list_insert_sorted (themeslist, DEFAULT_THEME, sort_alpha); // Open directory for reading directory = opendir (dirname); if (directory != NULL) // if directory exists { while ((file = readdir (directory)) != NULL) // do on each file { #ifdef DEBUGGING printf ("File: %s\n",file->d_name); #endif if (stat (g_strconcat (dirname,file->d_name,NULL), &buffer) < 0) { #ifdef DEBUGGING printf ("error finding stat info\n"); #endif } else if (buffer.st_mode & S_IFDIR && strcmp(file->d_name, ".") && strcmp (file->d_name, "..")) { #ifdef DEBUGGING printf ("directory\n"); #endif themeslist = g_list_insert_sorted (themeslist, file->d_name, sort_alpha); // it's a directory, add to list } } } gtk_combo_set_popdown_strings (GTK_COMBO(dancer->config.theme_combo), themeslist); g_list_free(themeslist); g_free (dirname); closedir (directory); } void config_themes_changed (GtkWidget *widget, GDancer *dancer) { // Set the dancer's theme g_snprintf (dancer->theme, 31, "%s", gtk_entry_get_text ( GTK_ENTRY(GTK_COMBO(dancer->config.theme_combo)->entry))); } void config_close (GtkWidget *widget, GDancer *dancer) { // get rid of the window close signal so this // function doesn't get called twice gtk_signal_disconnect_by_func (GTK_OBJECT(dancer->config.window), GTK_SIGNAL_FUNC(config_close), dancer); // Destroy all the configure window's widgets gtk_widget_destroy (dancer->config.close_button); dancer->config.close_button = NULL; gtk_widget_destroy (dancer->config.theme_combo); dancer->config.theme_combo = NULL; gtk_widget_destroy (dancer->config.theme_label); dancer->config.theme_label = NULL; gtk_widget_destroy (dancer->config.vbox); dancer->config.vbox = NULL; gtk_widget_destroy (dancer->config.window); dancer->config.window = NULL; // Switch the theme load_images (dancer); } void skip_frames_changed (GtkAdjustment *adjustment, GDancer *dancer) { // store value to global config dancer->skip_frames = (int) adjustment->value; // put the integer value back to make the slider change by whole // integers (cheesy little hack, only way I could figure out how // to do it) adjustment->value = dancer->skip_frames; } void move_dancers_changed (GtkToggleButton *button, GDancer *dancer) { dancer->move_dancer = gtk_toggle_button_get_active (button); } void config_dancer (GtkWidget *widget, GDancer *dancer) { // Config Window if (dancer->config.window) return; // Make the window and set properties dancer->config.window = gtk_window_new(GTK_WINDOW_DIALOG); gtk_window_set_title (GTK_WINDOW(dancer->config.window), "Configure"); // Make vertical Box and add it into window container dancer->config.vbox = gtk_vbox_new (FALSE, 3); gtk_container_add (GTK_CONTAINER(dancer->config.window), dancer->config.vbox); // Make theme label dancer->config.theme_label = gtk_label_new ("Choose a theme:"); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.theme_label, FALSE, FALSE, 3); // Make theme pulldown list dancer->config.theme_combo = gtk_combo_new(); gtk_entry_set_editable ( GTK_ENTRY(GTK_COMBO(dancer->config.theme_combo)->entry), FALSE); gtk_entry_set_text (GTK_ENTRY(GTK_COMBO(dancer->config.theme_combo)->entry), dancer->theme); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.theme_combo, FALSE, FALSE, 3); gtk_signal_connect( GTK_OBJECT(GTK_COMBO(dancer->config.theme_combo)->button), "pressed", GTK_SIGNAL_FUNC(config_themes_list), dancer); gtk_signal_connect( GTK_OBJECT(GTK_COMBO(dancer->config.theme_combo)->entry), "changed", GTK_SIGNAL_FUNC(config_themes_changed), dancer); // Make skip frames slider dancer->config.skiplabel = gtk_label_new ("Select the amount of frames to skip:"); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.skiplabel, FALSE, FALSE, 3); dancer->config.adjustment = gtk_adjustment_new ( dancer->skip_frames, // default value 0, // lower value 50, // upper value 1, // step increasement 2, // page increasement 1); // page size (for scrollbar, doesn't apply) gtk_signal_connect (GTK_OBJECT(dancer->config.adjustment), "value-changed", GTK_SIGNAL_FUNC(skip_frames_changed), dancer); dancer->config.skipslider = gtk_hscale_new (dancer->config.adjustment); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.skipslider, FALSE, FALSE, 3); // Make move dancer option toggle (to make dancer move around or not) dancer->config.movetoggle = gtk_check_button_new_with_label ( "Make dancers move around"); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(dancer->config.movetoggle), dancer->move_dancer); gtk_signal_connect (GTK_OBJECT(dancer->config.movetoggle), "toggled", GTK_SIGNAL_FUNC(move_dancers_changed), dancer); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.movetoggle, FALSE, FALSE, 3); // Make and add close button dancer->config.close_button = gtk_button_new_with_label ("Close"); gtk_signal_connect (GTK_OBJECT(dancer->config.close_button), "clicked", GTK_SIGNAL_FUNC(config_close), dancer); gtk_box_pack_start (GTK_BOX(dancer->config.vbox), dancer->config.close_button, FALSE, FALSE, 3); // connect signal for when windows gets closed gtk_signal_connect (GTK_OBJECT(dancer->config.window), "destroy", GTK_SIGNAL_FUNC(config_close), dancer); // Display widgets gtk_widget_show (dancer->config.vbox); gtk_widget_show (dancer->config.close_button); gtk_widget_show (dancer->config.movetoggle); gtk_widget_show (dancer->config.skipslider); gtk_widget_show (dancer->config.skiplabel); gtk_widget_show (dancer->config.theme_combo); gtk_widget_show (dancer->config.theme_label); gtk_widget_show (dancer->config.window); }