/* gcompris - click_on_letter.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 #include "gcompris/gcompris.h" #define SOUNDLISTFILE PACKAGE static GcomprisBoard *gcomprisBoard = NULL; static gboolean board_paused; static void start_board (GcomprisBoard *agcomprisBoard); static void pause_board (gboolean pause); static void end_board (void); static gboolean is_our_board (GcomprisBoard *gcomprisBoard); static void set_level (guint level); static int gamewon; static void process_ok(void); static void highlight_selected(GnomeCanvasItem *); static void game_won(void); static void repeat(void); static void config_start(GcomprisBoard *agcomprisBoard, GcomprisProfile *aProfile); static void config_stop(void); #define VERTICAL_SEPARATION 408 #define HORIZONTAL_SEPARATION 0 #define NUMBER_OF_SUBLEVELS 3 #define NUMBER_OF_LEVELS 5 #define MAX_NUMBER_OF_LETTERS 4 #define NOT_OK 0 #define OK 1 #define OK_NO_INIT 2 #define TEXT_COLOR "white" static GnomeCanvasGroup *boardRootItem = NULL; static GnomeCanvasItem *l_items[MAX_NUMBER_OF_LETTERS]; static GnomeCanvasItem *buttons[MAX_NUMBER_OF_LETTERS]; static GnomeCanvasItem *selected_button = NULL; static GnomeCanvasItem *click_on_letter_create_item(GnomeCanvasGroup *parent); static void click_on_letter_destroy_all_items(void); static void click_on_letter_next_level(void); static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data); static gboolean sounds_are_fine(); static int right_position; static int number_of_letters=MAX_NUMBER_OF_LETTERS; static gchar *right_letter; static gchar *alphabet; static void sound_played(gchar *file); static gboolean uppercase_only; /* Description of this plugin */ static BoardPlugin menu_bp = { NULL, NULL, "Read a letter", "Learn to recognize letters", "Pascal Georges pascal.georges1@free.fr>", NULL, NULL, NULL, NULL, start_board, pause_board, end_board, is_our_board, NULL, NULL, set_level, NULL, repeat, config_start, config_stop }; /* * Main entry point mandatory for each Gcompris's game * --------------------------------------------------- * */ GET_BPLUGIN_INFO(click_on_letter) /* * in : boolean TRUE = PAUSE : FALSE = CONTINUE * */ static void pause_board (gboolean pause) { if(gcomprisBoard==NULL) return; if(gamewon == TRUE && pause == FALSE) /* the game is won */ { game_won(); } board_paused = pause; } /* */ static void start_board (GcomprisBoard *agcomprisBoard) { GHashTable *config = gc_db_get_board_conf(); int ready; board_paused = TRUE; gc_locale_set(g_hash_table_lookup( config, "locale_sound")); gchar *up_init_str = g_hash_table_lookup( config, "uppercase_only"); if (up_init_str && (strcmp(up_init_str, "True")==0)) uppercase_only = TRUE; else uppercase_only = FALSE; g_hash_table_destroy(config); ready = sounds_are_fine(); gc_sound_bg_pause(); if (agcomprisBoard!=NULL) { gcomprisBoard=agcomprisBoard; gc_set_background(gnome_canvas_root(gcomprisBoard->canvas), "opt/scenery4_background.png"); gcomprisBoard->level=1; gcomprisBoard->maxlevel=NUMBER_OF_LEVELS; gcomprisBoard->sublevel=1; /* Go to next level after this number of 'play' */ gcomprisBoard->number_of_sublevel=NUMBER_OF_SUBLEVELS; if(ready) { /* Warning, bar buttons are set in click_on_letter_next_level() to avoid them to appear in the case a dialog is displayed */ gc_score_start(SCORESTYLE_NOTE, 50, 50, gcomprisBoard->number_of_sublevel); if(ready == OK) click_on_letter_next_level(); gamewon = FALSE; pause_board(FALSE); } } } /* ======================================= */ static void end_board () { if(gcomprisBoard!=NULL) { pause_board(TRUE); gc_score_end(); click_on_letter_destroy_all_items(); } gc_locale_reset(); gcomprisBoard = NULL; gc_sound_bg_resume(); } /* ======================================= */ static void set_level (guint level) { if(gcomprisBoard!=NULL) { gcomprisBoard->level=level; gcomprisBoard->sublevel=1; click_on_letter_next_level(); } } /* ======================================= */ static gboolean is_our_board (GcomprisBoard *gcomprisBoard) { if (gcomprisBoard) { if(g_strcasecmp(gcomprisBoard->type, "click_on_letter")==0) { /* Set the plugin entry */ gcomprisBoard->plugin=&menu_bp; return TRUE; } } return FALSE; } /* ======================================= */ static void repeat () { if(gcomprisBoard!=NULL) { gchar *str1 = NULL; gchar *right_letter_ogg = NULL; str1 = gc_sound_alphabet(right_letter); right_letter_ogg = g_strdup_printf("voices/$LOCALE/alphabet/%s", str1); g_free(str1); if(right_letter_ogg) { gc_sound_play_ogg_cb(right_letter_ogg, sound_played); } g_free(right_letter_ogg); } } static gboolean sounds_are_fine() { char *letter_str; char *str2; GcomprisProperties *properties = gc_prop_get(); if(!properties->fx) { gc_dialog(_("Error: this activity cannot be played with the\nsound effects disabled.\nGo to the configuration dialog to\nenable the sound"), gc_board_stop); return(NOT_OK); } /* TRANSLATORS: Put here the alphabet in your language */ alphabet=_("abcdefghijklmnopqrstuvwxyz"); g_assert(g_utf8_validate(alphabet, -1, NULL)); // require by all utf8-functions gchar *letter = g_new0(gchar, 8); g_unichar_to_utf8(g_utf8_get_char(alphabet), letter); letter_str = gc_sound_alphabet(letter); g_free(letter); str2 = gc_file_find_absolute("voices/$LOCALE/alphabet/%s", letter_str); if (!str2) { gchar *locale = NULL; locale = g_strndup(gc_locale_get(), 2); gc_locale_reset(); gc_locale_set("en_US"); str2 = gc_file_find_absolute("voices/en/alphabet/%s", letter_str); if (!str2) { gchar *msg = g_strdup_printf( _("Error: this activity requires that you first install\nthe packages with GCompris voices for the locale '%s' or '%s'"), locale, "en"); gc_dialog(msg, gc_board_stop); g_free(msg); return (NOT_OK); } else { gchar *msg = g_strdup_printf( _("Error: this activity requires that you first install\nthe packages with GCompris voices for the locale '%s' ! Fallback to english, sorry!"), locale); gc_dialog(msg, click_on_letter_next_level); g_free(msg); g_free(str2); return(OK_NO_INIT); } } else { g_free(str2); } return(OK); } /*-------------------------------------------------------------------------------*/ /*-------------------------------------------------------------------------------*/ /* set initial values for the next level */ static void click_on_letter_next_level() { /* It must be set it for the warning dialogs */ gc_bar_set(GC_BAR_CONFIG|GC_BAR_LEVEL|GC_BAR_REPEAT); gc_bar_set_level(gcomprisBoard); click_on_letter_destroy_all_items(); gamewon = FALSE; selected_button = NULL; gc_score_set(gcomprisBoard->sublevel); g_free (right_letter); /* Try the next level */ gc_sound_play_ogg("voices/$LOCALE/misc/click_on_letter.ogg", NULL); click_on_letter_create_item(gnome_canvas_root(gcomprisBoard->canvas)); } /* ==================================== */ /* Destroy all the items */ static void click_on_letter_destroy_all_items() { if(boardRootItem!=NULL) gtk_object_destroy (GTK_OBJECT(boardRootItem)); boardRootItem = NULL; } /* ==================================== */ static GnomeCanvasItem *click_on_letter_create_item(GnomeCanvasGroup *parent) { int xOffset,yOffset,i,j; GdkPixbuf *button_pixmap = NULL; int length_of_aphabet=g_utf8_strlen (alphabet,-1); number_of_letters=gcomprisBoard->level+1; if (number_of_letters>MAX_NUMBER_OF_LETTERS) number_of_letters=MAX_NUMBER_OF_LETTERS; int numbers[number_of_letters]; gchar *letters[number_of_letters]; g_assert(number_of_letters<=length_of_aphabet); // because we must set unique letter on every "vagon" for (i=0;ilevel) { case 1 : case 2 : letters[i]=g_strndup(copy_from,copy_to-copy_from); break; case 3 : letters[i]=g_utf8_strup(copy_from,copy_to-copy_from); break; default : if ( g_random_boolean() ) letters[i]=g_strndup(copy_from,copy_to-copy_from); else letters[i]=g_utf8_strup(copy_from,copy_to-copy_from); } } } /* */ right_position = g_random_int_range(0,number_of_letters); g_assert(right_position >= 0 && right_position < number_of_letters); right_letter = g_utf8_strdown(letters[right_position],-1); repeat(); boardRootItem = GNOME_CANVAS_GROUP( gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas), gnome_canvas_group_get_type (), "x", (double) 0, "y", (double) 0, NULL)); button_pixmap = gc_pixmap_load("images/wagon-yellow.png"); yOffset = VERTICAL_SEPARATION; xOffset = 5; for (i=0; i< number_of_letters; i++) { buttons[i] = gnome_canvas_item_new (boardRootItem, gnome_canvas_pixbuf_get_type (), "pixbuf", button_pixmap, "x", (double) xOffset, "y", (double) yOffset, NULL); l_items[i] = gnome_canvas_item_new (boardRootItem, gnome_canvas_text_get_type (), "text", letters[i], "font", gc_skin_font_board_huge_bold, "anchor", GTK_ANCHOR_CENTER, "fill_color_rgba", 0x0000ffff, "x", (double) xOffset + gdk_pixbuf_get_width(button_pixmap)/2, "y", (double) yOffset + gdk_pixbuf_get_height(button_pixmap)/2 - 5, NULL); g_free(letters[i]); xOffset +=HORIZONTAL_SEPARATION +gdk_pixbuf_get_width(button_pixmap); gtk_signal_connect(GTK_OBJECT(l_items[i]), "event", (GtkSignalFunc) item_event, GINT_TO_POINTER(i)); gtk_signal_connect(GTK_OBJECT(buttons[i]), "event", (GtkSignalFunc) item_event, GINT_TO_POINTER(i)); // gtk_signal_connect(GTK_OBJECT(buttons[i]), "event", (GtkSignalFunc) gc_item_focus_event, NULL); } gdk_pixbuf_unref(button_pixmap); return NULL; } /* ==================================== */ static void game_won() { gcomprisBoard->sublevel++; if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) { /* Try the next level */ gcomprisBoard->sublevel=1; gcomprisBoard->level++; if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out gc_bonus_end_display(GC_BOARD_FINISHED_TUXPLANE); return; } } click_on_letter_next_level(); } /* ==================================== */ static gboolean process_ok_timeout() { gc_bonus_display(gamewon, GC_BONUS_FLOWER); return FALSE; } static void process_ok() { // leave time to display the right answer g_timeout_add(TIME_CLICK_TO_BONUS, process_ok_timeout, NULL); } /* ==================================== */ static gint item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data) { int pos = GPOINTER_TO_INT(data); double item_x, item_y; item_x = event->button.x; item_y = event->button.y; gnome_canvas_item_w2i(item->parent, &item_x, &item_y); if(board_paused) return FALSE; switch (event->type) { case GDK_BUTTON_PRESS: /* We really don't want the user to change his/her mind */ board_paused = TRUE; if ( pos == right_position ) { gamewon = TRUE; } else { gamewon = FALSE; } highlight_selected(item); process_ok(); break; default: break; } return FALSE; } /* ==================================== */ static void highlight_selected(GnomeCanvasItem * item) { GdkPixbuf *button_pixmap_selected = NULL, *button_pixmap = NULL; GnomeCanvasItem *button; int i; /* Replace text item by button item */ button = item; for (i=0; i%s configuration\n for profile %s"), agcomprisBoard->name, aProfile ? aProfile->name : ""); GcomprisBoardConf *bconf; bconf = gc_board_config_window_display(label, conf_ok); g_free(label); /* init the combo to previously saved value */ GHashTable *config = gc_db_get_conf( profile_conf, board_conf); gchar *saved_locale_sound = g_hash_table_lookup( config, "locale_sound"); gc_board_config_combo_locales_asset(bconf, "Select sound locale", saved_locale_sound, "voices/$LOCALE/colors/purple.ogg"); gboolean up_init = FALSE; gchar *up_init_str = g_hash_table_lookup( config, "uppercase_only"); if (up_init_str && (strcmp(up_init_str, "True")==0)) up_init = TRUE; gc_board_config_boolean_box(bconf, _("Uppercase only text"), "uppercase_only", up_init); g_hash_table_destroy(config); } /* ======================= */ /* = config_stop = */ /* ======================= */ static void config_stop() { } static void sound_played (gchar *file) { g_warning ("Sound_played %s\n", file); }