/* gcompris - board_config.c * * Copyright (C) 2001 Pascal Georges * * 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 3 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, see . */ #include #include "gcompris.h" #include "board_config_common.h" static GcomprisBoard *config_board; void gc_board_config_start(GcomprisBoard *aBoard, GcomprisProfile *aProfile) { if (aBoard->plugin == NULL){ g_warning("gc_board_config_start: board %s/%s is not initialised ? Hummmm...", aBoard->section,aBoard->name); return; } if (aBoard->plugin->config_start == NULL) { g_warning("Trying to configure board %s/%s without config_start", aBoard->section,aBoard->name); return; } config_board = aBoard; aBoard->plugin->config_start(aBoard, aProfile); return; } void gc_board_config_stop() { if (!config_board) return; config_board->plugin->config_stop(); config_board = NULL; return; } void gc_board_conf_close (GtkDialog *dialog, gpointer user_data) { GcomprisBoardConf *u= (GcomprisBoardConf*)user_data; gtk_object_destroy(GTK_OBJECT(dialog)); g_hash_table_destroy (u->hash_conf); u->hash_conf = NULL; /* in case we close without response */ if (u->Confcallback){ u->Confcallback(NULL); u->Confcallback = NULL; } g_free(u); } void _response_board_conf (GtkButton *button, gint arg1, gpointer user_data) { GcomprisBoardConf *u= (GcomprisBoardConf*)user_data; if (u->Confcallback){ switch (arg1){ case GTK_RESPONSE_APPLY: u->Confcallback(u->hash_conf); break; case GTK_RESPONSE_CANCEL: u->Confcallback(NULL); break; case GTK_RESPONSE_NONE: u->Confcallback(NULL); break; default: u->Confcallback(NULL); break; } u->Confcallback = NULL; } gc_board_conf_close (GTK_DIALOG(u->conf_window), u); } #ifdef XF86_VIDMODE static GdkEventConfigure last_configure_event; static gint _conf_window_configured(GtkWindow *window, GdkEventConfigure *event, gpointer param) { GcomprisBoardConf *u= (GcomprisBoardConf*)param; gint new_x, new_y; double screen_width, screen_height; /* Because we call gtk_window_move, we cause a configure event. Filter out identical events to avoid looping. */ if (memcmp(&last_configure_event, event, sizeof(GdkEventConfigure))) { gnome_canvas_get_scroll_region( GNOME_CANVAS( gtk_bin_get_child( GTK_BIN( gc_get_window()))), NULL, NULL, &screen_width, &screen_height); /* strange but gcompris.c sets the scrollheight to screen_height + 30 */ screen_height -= 30; new_x = ((gint)screen_width - event->width) / 2; new_y = ((gint)screen_height - event->height) / 2; /* printf("screen %dx%d, window %dx%d, place %dx%d\n", (int)screen_width, (int)screen_height, event->width, event->height, new_x, new_y); */ gtk_window_move (u->conf_window, new_x, new_y); memcpy(&last_configure_event, event, sizeof(GdkEventConfigure)); } /* Act as if we aren't there / aren't hooked up */ return FALSE; } #endif GcomprisBoardConf * gc_board_config_window_display(gchar *label, GcomprisConfCallback callback) { GtkWidget *header; GcomprisBoardConf *config; config = g_malloc0(sizeof(GcomprisBoardConf)); /* init static values or callbacks */ config->Confcallback = callback; config->hash_conf = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free); /* Creating a config window will cause our main window to loose focus, this tells the main window to ignore the next focus out event (and thus stay in fullscreen mode if we're fullscreen). */ gc_ignore_next_focus_out(); /* main configuration window */ config->conf_window = \ GTK_WINDOW(gtk_dialog_new_with_buttons ("GCompris", GTK_WINDOW(gtk_widget_get_toplevel (GTK_WIDGET(gc_board_get_current()->canvas))), GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT, GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_APPLY, GTK_RESPONSE_APPLY, NULL)); /* parameters */ #ifdef XF86_VIDMODE if (gc_prop_get()->fullscreen && !gc_prop_get()->noxf86vm) { memset(&last_configure_event, 0, sizeof(GdkEventConfigure)); gtk_widget_add_events(GTK_WIDGET(config->conf_window), GDK_STRUCTURE_MASK); gtk_signal_connect (GTK_OBJECT (config->conf_window), "configure_event", GTK_SIGNAL_FUNC (_conf_window_configured), config); } else #endif gtk_window_set_position (config->conf_window, GTK_WIN_POS_CENTER_ALWAYS); gtk_widget_show(GTK_WIDGET(config->conf_window)); GcomprisProperties *properties = gc_prop_get(); if (properties->fullscreen && !properties->noxf86vm) if (gdk_pointer_grab(gc_get_window()->window, TRUE, 0, gc_get_window()->window, NULL, GDK_CURRENT_TIME) != GDK_GRAB_SUCCESS) g_warning("Pointer grab failed"); /* main vbox in window */ config->main_conf_box = GTK_VBOX(GTK_DIALOG(config->conf_window)->vbox); g_signal_connect(G_OBJECT(config->conf_window), "response", G_CALLBACK(_response_board_conf), config); g_signal_connect (G_OBJECT(config->conf_window), "close", G_CALLBACK(gc_board_conf_close), config); /* Label header */ header = gtk_label_new ((gchar *)NULL); gtk_widget_show(header); gtk_box_pack_start (GTK_BOX(config->main_conf_box), header, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(header), GTK_JUSTIFY_CENTER); gchar *label_markup = NULL; label_markup = g_strdup_printf("%s",label); gtk_label_set_markup (GTK_LABEL(header), (const gchar *)label_markup); g_free(label_markup); gc_board_conf_separator(config); return config; } void gc_board_conf_boolean_box_toggled (GtkToggleButton *togglebutton, gpointer key) { _gc_boardconf_key *u = (_gc_boardconf_key*)key; gchar *the_key = g_strdup(u->key); gchar *value; if (gtk_toggle_button_get_active (togglebutton)) value = g_strdup("True"); else value = g_strdup("False"); g_hash_table_replace(u->config->hash_conf, (gpointer) the_key, (gpointer) value); } GtkCheckButton * gc_board_config_boolean_box(GcomprisBoardConf *config, const gchar *label, gchar *key, gboolean initial_value) { _gc_boardconf_key *user_data; g_return_val_if_fail(config, NULL); check_key( key); GtkWidget *CheckBox = gtk_check_button_new_with_label (label); gtk_widget_show(CheckBox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), CheckBox, FALSE, FALSE, 0); gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON(CheckBox), initial_value); user_data = g_malloc0(sizeof(_gc_boardconf_key)); user_data -> key =g_strdup(key); user_data -> config = config; g_signal_connect (G_OBJECT(CheckBox), "toggled", G_CALLBACK(gc_board_conf_boolean_box_toggled), user_data); g_signal_connect (G_OBJECT(CheckBox), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), user_data); return GTK_CHECK_BUTTON(CheckBox); } static void spin_changed (GtkSpinButton *spinbutton, gpointer data) { _gc_boardconf_key *u = (_gc_boardconf_key*)data; gchar *h_key = g_strdup(u->key); gchar *h_value = g_strdup_printf("%d",gtk_spin_button_get_value_as_int (spinbutton)); g_hash_table_replace (u->config->hash_conf, h_key, h_value); } GtkSpinButton * gc_board_config_spin_int(GcomprisBoardConf *config, const gchar *label, gchar *key, gint min, gint max, gint step, gint init) { g_return_val_if_fail(config, NULL); check_key( key); GtkWidget *spin; GtkWidget *hbox = gtk_hbox_new (FALSE, 8); GtkWidget *label_spin; gtk_widget_show(hbox); gtk_box_pack_start (GTK_BOX(config->main_conf_box), hbox, FALSE, FALSE, 0); /* Label */ label_spin = gtk_label_new ((gchar *)NULL); gtk_widget_show(label_spin); gtk_box_pack_start (GTK_BOX(hbox), label_spin, FALSE, FALSE, 0); gtk_label_set_justify (GTK_LABEL(label_spin), GTK_JUSTIFY_RIGHT); gtk_label_set_markup (GTK_LABEL(label_spin), (const gchar *)label); spin = gtk_spin_button_new_with_range ((gdouble )min, (gdouble )max, (gdouble )step); gtk_widget_show(spin); gtk_box_pack_start (GTK_BOX(hbox), spin, FALSE, FALSE, 0); gtk_spin_button_set_wrap ( GTK_SPIN_BUTTON(spin), TRUE); gtk_spin_button_set_numeric ( GTK_SPIN_BUTTON(spin), TRUE); gtk_spin_button_set_digits ( GTK_SPIN_BUTTON(spin), 0); gtk_spin_button_set_value ( GTK_SPIN_BUTTON(spin), (gdouble) init); _gc_boardconf_key *u = g_malloc0(sizeof(_gc_boardconf_key)); u->key = g_strdup(key); u->config = config; g_signal_connect (G_OBJECT(spin), "value-changed", G_CALLBACK(spin_changed), u); g_signal_connect( G_OBJECT(spin), "destroy", G_CALLBACK(_gc_destroy_boardconf_key), u); return GTK_SPIN_BUTTON(spin); } GtkHSeparator * gc_board_conf_separator(GcomprisBoardConf *config) { g_return_val_if_fail(config, NULL); GtkWidget *separator = gtk_hseparator_new (); gtk_widget_show(separator); gtk_box_pack_start (GTK_BOX(config->main_conf_box), separator, FALSE, FALSE, 8); return GTK_HSEPARATOR(separator); }