Back to index

gcompris  8.2.2
bar.c
Go to the documentation of this file.
00001 /* gcompris - bar.c
00002  *
00003  * Time-stamp: <2006/08/21 23:27:39 bruno>
00004  *
00005  * Copyright (C) 2000-2003 Bruno Coudoin
00006  *
00007  *   This program is free software; you can redistribute it and/or modify
00008  *   it under the terms of the GNU General Public License as published by
00009  *   the Free Software Foundation; either version 2 of the License, or
00010  *   (at your option) any later version.
00011  *
00012  *   This program is distributed in the hope that it will be useful,
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  *   GNU General Public License for more details.
00016  *
00017  *   You should have received a copy of the GNU General Public License
00018  *   along with this program; if not, write to the Free Software
00019  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020  */
00021 
00027 #include <string.h>
00028 
00029 #include "gcompris.h"
00030 #include "gc_core.h"
00031 #include "gcompris_config.h"
00032 #include "about.h"
00033 
00034 #define SOUNDLISTFILE PACKAGE
00035 
00036 #define BAR_GAP             15     /* Value used to fill space above and under icons in the bar */
00037 #define NUMBER_OF_ITEMS 10  /* Number of buttons in the bar                              */
00038 
00039 static void    update_exit_button();
00040 static gint    item_event_bar(GnomeCanvasItem *item, GdkEvent *event, gchar *data);
00041 static void    bar_reset_sound_id (void);
00042 
00043 static gint current_level = -1;
00044 static gint current_flags = -1;
00045 static GnomeCanvasItem *bar_item  = NULL;
00046 static GnomeCanvasItem *exit_item = NULL;
00047 static GnomeCanvasItem *home_item = NULL;
00048 static GnomeCanvasItem *level_item = NULL;
00049 static GnomeCanvasItem *ok_item = NULL;
00050 static GnomeCanvasItem *help_item = NULL;
00051 static GnomeCanvasItem *repeat_item = NULL;
00052 static GnomeCanvasItem *config_item = NULL;
00053 static GnomeCanvasItem *about_item = NULL;
00054 static guint level_handler_id;
00055 
00056 static gint sound_play_id = 0;
00057 
00058 static void  confirm_quit(gboolean answer);
00059 
00060 /*
00061  * Main entry point
00062  * ----------------
00063  *
00064  */
00065 
00066 
00067 /*
00068  * Do all the bar display and register the events
00069  */
00070 void gc_bar_start (GnomeCanvas *theCanvas)
00071 {
00072   GcomprisProperties *properties = gc_prop_get();
00073   GdkPixbuf   *pixmap = NULL;
00074   GnomeCanvasItem *rootitem;
00075   gint16           width, height;
00076   double           zoom;
00077 
00078   width  = BOARDWIDTH;
00079   height = BARHEIGHT-2;
00080 
00081   bar_reset_sound_id();
00082 
00083   rootitem = \
00084     gnome_canvas_item_new (gnome_canvas_root(theCanvas),
00085                         gnome_canvas_group_get_type (),
00086                         "x", (double)0,
00087                         "y", (double)0,
00088                         NULL);
00089 
00090   pixmap = gc_skin_pixmap_load("bar_bg.jpg");
00091   bar_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00092                             gnome_canvas_pixbuf_get_type (),
00093                             "pixbuf", pixmap,
00094                             "x", (double) 0,
00095                             "y", (double) 0,
00096                             NULL);
00097   gdk_pixbuf_unref(pixmap);
00098 
00099   // EXIT
00100   if(properties->disable_quit == 0)
00101     {
00102       pixmap = gc_skin_pixmap_load("button_exit.png");
00103       zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00104       exit_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00105                                     gnome_canvas_pixbuf_get_type (),
00106                                     "pixbuf", pixmap,
00107                                     "x", (double) (width/NUMBER_OF_ITEMS) * 1 -
00108                                     gdk_pixbuf_get_width(pixmap)/2,
00109                                     "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00110                                     NULL);
00111       gdk_pixbuf_unref(pixmap);
00112 
00113       gtk_signal_connect(GTK_OBJECT(exit_item), "event",
00114                       (GtkSignalFunc) item_event_bar,
00115                       "quit");
00116 
00117       gtk_signal_connect(GTK_OBJECT(exit_item), "event",
00118                       (GtkSignalFunc) gc_item_focus_event,
00119                       NULL);
00120     }
00121 
00122   // HOME
00123   pixmap = gc_skin_pixmap_load("home.png");
00124   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00125   home_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00126                                  gnome_canvas_pixbuf_get_type (),
00127                                  "pixbuf", pixmap,
00128                                  "x", (double) (width/NUMBER_OF_ITEMS) * 9 -
00129                                  gdk_pixbuf_get_width(pixmap)/2,
00130                                  "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00131                                  NULL);
00132   gdk_pixbuf_unref(pixmap);
00133 
00134   gtk_signal_connect(GTK_OBJECT(home_item), "event",
00135                    (GtkSignalFunc) item_event_bar,
00136                    "back");
00137 
00138   gtk_signal_connect(GTK_OBJECT(home_item), "event",
00139                    (GtkSignalFunc) gc_item_focus_event,
00140                    NULL);
00141 
00142 
00143   // OK
00144   pixmap = gc_skin_pixmap_load("ok.png");
00145   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00146   ok_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00147                                gnome_canvas_pixbuf_get_type (),
00148                                "pixbuf", pixmap,
00149                                "x", (double) (width/NUMBER_OF_ITEMS) * 7 -
00150                                gdk_pixbuf_get_width(pixmap)/2,
00151                                "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00152                                NULL);
00153   gdk_pixbuf_unref(pixmap);
00154 
00155   gtk_signal_connect(GTK_OBJECT(ok_item), "event",
00156                    (GtkSignalFunc) item_event_bar,
00157                    "ok");
00158 
00159   gtk_signal_connect(GTK_OBJECT(ok_item), "event",
00160                    (GtkSignalFunc) gc_item_focus_event,
00161                    NULL);
00162 
00163 
00164   // LEVEL
00165   pixmap = gc_skin_pixmap_load("level1.png");
00166   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00167   level_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00168                                   gnome_canvas_pixbuf_get_type (),
00169                                   "pixbuf", pixmap,
00170                                   "x", (double) (width/NUMBER_OF_ITEMS) * 5 -
00171                                   gdk_pixbuf_get_width(pixmap)/2,
00172                                   "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00173                                   NULL);
00174   gdk_pixbuf_unref(pixmap);
00175 
00176   current_level = 1;
00177   gtk_signal_connect(GTK_OBJECT(level_item), "event",
00178                    (GtkSignalFunc) item_event_bar,
00179                    "level");
00180 
00181   level_handler_id =   gtk_signal_connect(GTK_OBJECT(level_item), "event",
00182                                      (GtkSignalFunc) gc_item_focus_event,
00183                                      NULL);
00184 
00185   // REPEAT
00186   pixmap = gc_skin_pixmap_load("repeat.png");
00187   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00188   repeat_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00189                                    gnome_canvas_pixbuf_get_type (),
00190                                    "pixbuf", pixmap,
00191                                    "x", (double) (width/NUMBER_OF_ITEMS) * 6 -
00192                                    gdk_pixbuf_get_width(pixmap)/2,
00193                                    "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00194                                    NULL);
00195   gdk_pixbuf_unref(pixmap);
00196 
00197   gtk_signal_connect(GTK_OBJECT(repeat_item), "event",
00198                    (GtkSignalFunc) item_event_bar,
00199                    "repeat");
00200 
00201   gtk_signal_connect(GTK_OBJECT(repeat_item), "event",
00202                    (GtkSignalFunc) gc_item_focus_event,
00203                    NULL);
00204 
00205   // HELP
00206   pixmap = gc_skin_pixmap_load("help.png");
00207   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00208   help_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00209                                  gnome_canvas_pixbuf_get_type (),
00210                                  "pixbuf", pixmap,
00211                                  "x", (double) (width/NUMBER_OF_ITEMS) * 4 -
00212                                  gdk_pixbuf_get_width(pixmap)/2,
00213                                  "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00214                                  NULL);
00215   gdk_pixbuf_unref(pixmap);
00216 
00217   gtk_signal_connect(GTK_OBJECT(help_item), "event",
00218                    (GtkSignalFunc) item_event_bar,
00219                    "help");
00220 
00221   gtk_signal_connect(GTK_OBJECT(help_item), "event",
00222                    (GtkSignalFunc) gc_item_focus_event,
00223                    NULL);
00224 
00225   // CONFIG
00226   if(properties->disable_config == 0)
00227     {
00228       pixmap = gc_skin_pixmap_load("config.png");
00229       zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00230       config_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00231                                       gnome_canvas_pixbuf_get_type (),
00232                                       "pixbuf", pixmap,
00233                                       "x", (double) (width/NUMBER_OF_ITEMS) * 3 -
00234                                       gdk_pixbuf_get_width(pixmap)/2,
00235                                       "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00236                                       NULL);
00237       gdk_pixbuf_unref(pixmap);
00238 
00239       gtk_signal_connect(GTK_OBJECT(config_item), "event",
00240                       (GtkSignalFunc) item_event_bar,
00241                       "configuration");
00242 
00243       gtk_signal_connect(GTK_OBJECT(config_item), "event",
00244                       (GtkSignalFunc) gc_item_focus_event,
00245                       NULL);
00246     }
00247 
00248   // ABOUT
00249   pixmap = gc_skin_pixmap_load("about.png");
00250   zoom = (double)(height-BAR_GAP)/(double)gdk_pixbuf_get_height(pixmap);
00251   about_item = gnome_canvas_item_new (GNOME_CANVAS_GROUP(rootitem),
00252                                  gnome_canvas_pixbuf_get_type (),
00253                                  "pixbuf", pixmap,
00254                                  "x", (double) (width/NUMBER_OF_ITEMS) * 2 -
00255                                  gdk_pixbuf_get_width(pixmap)/2,
00256                                  "y", (double) (height-gdk_pixbuf_get_height(pixmap)*zoom)/2,
00257                                  NULL);
00258   gdk_pixbuf_unref(pixmap);
00259 
00260   gtk_signal_connect(GTK_OBJECT(about_item), "event",
00261                    (GtkSignalFunc) item_event_bar,
00262                    "about");
00263 
00264   gtk_signal_connect(GTK_OBJECT(about_item), "event",
00265                    (GtkSignalFunc) gc_item_focus_event,
00266                    NULL);
00267 
00268   // Show them all
00269   update_exit_button();
00270   gnome_canvas_item_hide(level_item);
00271   gnome_canvas_item_hide(ok_item);
00272   gnome_canvas_item_hide(help_item);
00273   gnome_canvas_item_hide(repeat_item);
00274   if(config_item)
00275     gnome_canvas_item_hide(config_item);
00276   gnome_canvas_item_hide(about_item);
00277 }
00278 
00279 
00280 void gc_bar_set_level(GcomprisBoard *gcomprisBoard)
00281 {
00282   char *str = NULL;
00283   GdkPixbuf *pixmap = NULL;
00284 
00285   /* Non yet initialized : Something Wrong */
00286   if(level_item==NULL)
00287     {
00288       g_message("in bar_set_level, level_item uninitialized : should not happen\n");
00289       return;
00290     }
00291 
00292   if(gcomprisBoard!=NULL)
00293     {
00294 
00295       str = g_strdup_printf("level%d.png", gcomprisBoard->level);
00296       pixmap = gc_skin_pixmap_load(str);
00297 
00298       g_free(str);
00299       /* Warning changing the image needs to free the focus first */
00300       gc_item_focus_free(level_item, NULL);
00301 
00302       gnome_canvas_item_set (level_item,
00303                           "pixbuf", pixmap,
00304                           NULL);
00305       gdk_pixbuf_unref(pixmap);
00306     }
00307 
00308   current_level=gcomprisBoard->level;
00309 }
00310 
00311 
00312 
00313 /* gc_bar_set_repeat_icon
00314  *
00315  * Override the repeat icon to a new one specific to your current board.
00316  * This must be called before calling gc_bar_set with GC_BAR_REPEAT_ICON
00317  * the given pixmap is not freed.
00318  *
00319  * Next call to gc_bar_set with GC_BAR_REPEAT will restore the default icon.
00320  *
00321  */
00322 void
00323 gc_bar_set_repeat_icon (GdkPixbuf *pixmap)
00324 {
00325   /* Warning changing the image needs to update pixbuf_ref for the focus usage */
00326   gc_item_focus_free(repeat_item, NULL);
00327   gnome_canvas_item_set (repeat_item,
00328                       "pixbuf", pixmap,
00329                       NULL);
00330 }
00331 
00332 /* Setting list of available icons in the control bar */
00333 void
00334 gc_bar_set (const GComprisBarFlags flags)
00335 {
00336 
00337   current_flags = flags;
00338 
00339   update_exit_button();
00340 
00341   if(flags&GC_BAR_LEVEL)
00342     gnome_canvas_item_show(level_item);
00343   else
00344     gnome_canvas_item_hide(level_item);
00345 
00346   if(flags&GC_BAR_OK)
00347     gnome_canvas_item_show(ok_item);
00348   else
00349     gnome_canvas_item_hide(ok_item);
00350 
00351   if(gc_help_has_board(gc_board_get_current()))
00352     gnome_canvas_item_show(help_item);
00353   else
00354     gnome_canvas_item_hide(help_item);
00355 
00356   if(flags&GC_BAR_REPEAT) {
00357     GdkPixbuf *pixmap;
00358 
00359     /* Set the repeat icon to the original one */
00360     pixmap = gc_skin_pixmap_load("repeat.png");
00361     gnome_canvas_item_set (repeat_item,
00362                         "pixbuf", pixmap,
00363                         NULL);
00364     gdk_pixbuf_unref(pixmap);
00365 
00366     gnome_canvas_item_show(repeat_item);
00367   } else {
00368 
00369     if(flags&GC_BAR_REPEAT_ICON)
00370       gnome_canvas_item_show(repeat_item);
00371     else
00372       gnome_canvas_item_hide(repeat_item);
00373   }
00374 
00375   if(flags&GC_BAR_CONFIG && config_item)
00376     gnome_canvas_item_show(config_item);
00377   else
00378     gnome_canvas_item_hide(config_item);
00379 
00380   if(flags&GC_BAR_ABOUT)
00381     gnome_canvas_item_show(about_item);
00382   else
00383     gnome_canvas_item_hide(about_item);
00384 
00385   /* FIXME : Workaround for bugged canvas */
00386   //  gnome_canvas_update_now(gc_board_get_current()->canvas);
00387 
00388 }
00389 
00390 /* Hide all icons in the control bar
00391  * or retore the icons to the previous value
00392  */
00393 void
00394 gc_bar_hide (gboolean hide)
00395 {
00396   if(hide)
00397     {
00398       if(exit_item)
00399        gnome_canvas_item_hide(exit_item);
00400       gnome_canvas_item_hide(home_item);
00401       gnome_canvas_item_hide(level_item);
00402       gnome_canvas_item_hide(ok_item);
00403       gnome_canvas_item_hide(help_item);
00404       gnome_canvas_item_hide(repeat_item);
00405       if(config_item)
00406        gnome_canvas_item_hide(config_item);
00407       gnome_canvas_item_hide(about_item);
00408     }
00409   else
00410     {
00411       gnome_canvas_item_show(home_item);
00412       gc_bar_set(current_flags);
00413     }
00414 }
00415 
00416 /*-------------------------------------------------------------------------------*/
00417 /*-------------------------------------------------------------------------------*/
00418 /*-------------------------------------------------------------------------------*/
00419 /*-------------------------------------------------------------------------------*/
00420 
00421 /*
00422  * Display or not the exit button
00423  */
00424 static void update_exit_button()
00425 {
00426 
00427   if(gc_board_get_current() == NULL)
00428     return;
00429 
00430   if (gc_board_get_current()->previous_board == NULL)
00431     {
00432       /* We are in the upper menu: show it */
00433       if(exit_item)
00434        gnome_canvas_item_show(exit_item);
00435       gnome_canvas_item_hide(home_item);
00436     }
00437   else
00438     {
00439       if(exit_item)
00440        gnome_canvas_item_hide(exit_item);
00441       gnome_canvas_item_show(home_item);
00442     }
00443 }
00444 
00445 /*
00446  * This is called to play sound
00447  *
00448  */
00449 static gint bar_play_sound (gchar *sound)
00450 {
00451   int policy = gc_sound_policy_get();
00452   gchar *str;
00453   gc_sound_policy_set(PLAY_ONLY_IF_IDLE);
00454 
00455   str = g_strdup_printf("sounds/$LOCALE/misc/%s.ogg", sound);
00456 
00457   gc_sound_play_ogg(str, NULL);
00458 
00459   g_free(str);
00460 
00461   gc_sound_policy_set(policy);
00462   sound_play_id = 0;
00463   return (FALSE);
00464 }
00465 
00466 static void bar_reset_sound_id ()
00467 {
00468   if(sound_play_id)
00469     gtk_timeout_remove (sound_play_id);
00470 
00471   sound_play_id=0;
00472 }
00473 
00474 /* Callback for the bar operations */
00475 static gint
00476 item_event_bar(GnomeCanvasItem *item, GdkEvent *event, gchar *data)
00477 {
00478   GcomprisBoard *gcomprisBoard = gc_board_get_current();
00479 
00480   switch (event->type)
00481     {
00482     case GDK_ENTER_NOTIFY:
00483       bar_reset_sound_id();
00484       sound_play_id = gtk_timeout_add (1000, (GtkFunction) bar_play_sound, data);
00485       break;
00486     case GDK_LEAVE_NOTIFY:
00487       bar_reset_sound_id();
00488       break;
00489     case GDK_BUTTON_PRESS:
00490       bar_reset_sound_id();
00491 
00492       /* This is not perfect clean but it makes it easy to remove the help window
00493         by clicking on any button in the bar */
00494       if(strcmp((char *)data, "help"))
00495        gc_help_stop ();
00496 
00497       if(!strcmp((char *)data, "ok"))
00498        {
00499          if(gcomprisBoard!=NULL)
00500            {
00501              if(gcomprisBoard->plugin->ok != NULL)
00502               {
00503                 gcomprisBoard->plugin->ok();
00504               }
00505            }
00506        }
00507       else if(!strcmp((char *)data, "level"))
00508        {
00509          gint tmp = current_level;
00510 
00511          current_level++;
00512          if(current_level>gcomprisBoard->maxlevel)
00513            current_level=1;
00514 
00515          if(tmp!=current_level)
00516            {
00517              gchar *str_number;
00518 
00519              gchar *number_str = g_strdup_printf("%d", current_level);
00520              gchar *current_level_str = gc_sound_alphabet(number_str);
00521              g_free(number_str);
00522 
00523              str_number = g_strdup_printf("sounds/$LOCALE/alphabet/%s", current_level_str);
00524 
00525              gc_sound_play_ogg("sounds/$LOCALE/misc/level.ogg", str_number, NULL);
00526 
00527              g_free(str_number);
00528              g_free(current_level_str);
00529            }
00530 
00531          if(gcomprisBoard->plugin->set_level != NULL)
00532            {
00533              gcomprisBoard->plugin->set_level(current_level);
00534            }
00535        }
00536       else if(!strcmp((char *)data, "back"))
00537        {
00538          gc_sound_play_ogg ("gobble", NULL);
00539          gc_bar_hide (TRUE);
00540          gc_board_stop();
00541        }
00542       else if(!strcmp((char *)data, "help"))
00543        {
00544          gc_sound_play_ogg ("gobble", NULL);
00545          gc_help_start(gcomprisBoard);
00546        }
00547       else if(!strcmp((char *)data, "repeat"))
00548        {
00549          if(gcomprisBoard->plugin->repeat != NULL)
00550            {
00551              gcomprisBoard->plugin->repeat();
00552            }
00553        }
00554       else if(!strcmp((char *)data, "configuration"))
00555        {
00556          if(gcomprisBoard->plugin->config_start != NULL)
00557            {
00558              gcomprisBoard->plugin->config_start(gcomprisBoard,
00559                                             gc_profile_get_current());
00560            }
00561        }
00562       else if(!strcmp((char *)data, "about"))
00563        {
00564          gc_about_start();
00565        }
00566       else if(!strcmp((char *)data, "quit"))
00567        {
00568          gc_confirm_box( _("GCompris confirmation"),
00569                          _("Are you sure you want to quit?"),
00570                          _("Yes, I am sure!"),
00571                          _("No, I want to keep going"),
00572                          (ConfirmCallBack) confirm_quit);
00573        }
00574       break;
00575 
00576     default:
00577       break;
00578     }
00579   return FALSE;
00580 
00581 }
00582 
00583 static void
00584 confirm_quit(gboolean answer)
00585 {
00586   if (answer)
00587     gc_exit();
00588 }