Back to index

gcompris  8.2.2
clockgame.c
Go to the documentation of this file.
00001 /* gcompris - clockgame.c
00002  *
00003  * Time-stamp: <2006/08/21 23:33:07 bruno>
00004  *
00005  * Copyright (C) 2000 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 
00022 #include <ctype.h>
00023 #include <math.h>
00024 
00025 #include "gcompris/gcompris.h"
00026 
00027 #define SOUNDLISTFILE PACKAGE
00028 
00029 static GcomprisBoard *gcomprisBoard = NULL;
00030 static gboolean board_paused = TRUE;
00031 
00032 static GnomeCanvasGroup *boardRootItem = NULL;
00033 
00034 static GnomeCanvasItem *second_item;
00035 static GnomeCanvasItem *hour_item;
00036 static GnomeCanvasItem *minute_item;
00037 static GnomeCanvasItem *digital_time_item;
00038 static GnomeCanvasItem *digital_time_item_s;
00039 static GnomeCanvasItem *time_to_find_item;
00040 static GnomeCanvasItem *time_to_find_item_s;
00041 
00042 /* Center of the clock and it's size */
00043 double cx;
00044 double cy;
00045 double clock_size;
00046 
00047 typedef struct {
00048   guint hour;
00049   guint minute;
00050   guint second;
00051 } GcomprisTime;
00052 static GcomprisTime timeToFind, currentTime;
00053 
00054 static void           start_board (GcomprisBoard *agcomprisBoard);
00055 static void           pause_board (gboolean pause);
00056 static void           end_board (void);
00057 static gboolean              is_our_board (GcomprisBoard *gcomprisBoard);
00058 static void           set_level (guint level);
00059 static void           process_ok(void);
00060 
00061 static int gamewon;
00062 static void           game_won(void);
00063 
00064 static void           clockgame_create_item(GnomeCanvasGroup *parent);
00065 static void           destroy_all_items(void);
00066 static void           get_random_hour(GcomprisTime *time);
00067 static void           clockgame_next_level(void);
00068 static gint           item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data);
00069 static void           display_hour(guint hour);
00070 static void           display_minute(guint minute);
00071 static void           display_second(guint second);
00072 static gboolean              time_equal(GcomprisTime *time1, GcomprisTime *time2);
00073 
00074 /* Description of this plugin */
00075 static BoardPlugin menu_bp =
00076 {
00077    NULL,
00078    NULL,
00079    "Learning Clock",
00080    "Learn how to tell the time",
00081    "Bruno Coudoin <bruno.coudoin@free.fr>",
00082    NULL,
00083    NULL,
00084    NULL,
00085    NULL,
00086    start_board,
00087    pause_board,
00088    end_board,
00089    is_our_board,
00090    NULL,
00091    process_ok,
00092    set_level,
00093    NULL,
00094    NULL,
00095    NULL,
00096    NULL
00097 };
00098 
00099 
00100 /*
00101  * Main entry point mandatory for each Gcompris's game
00102  * ---------------------------------------------------
00103  *
00104  */
00105 
00106 GET_BPLUGIN_INFO(clockgame)
00107 
00108 /*
00109  * in : boolean TRUE = PAUSE : FALSE = CONTINUE
00110  *
00111  */
00112 static void pause_board (gboolean pause)
00113 {
00114 
00115   if(gcomprisBoard==NULL)
00116     return;
00117 
00118   if(gamewon == TRUE && pause == FALSE) /* the game is won */
00119     {
00120       game_won();
00121     }
00122 
00123   board_paused = pause;
00124 }
00125 
00126 /*
00127  */
00128 static void start_board (GcomprisBoard *agcomprisBoard)
00129 {
00130 
00131   if(agcomprisBoard!=NULL)
00132     {
00133       gchar *img;
00134       gcomprisBoard=agcomprisBoard;
00135 
00136       img = gc_skin_image_get("clockgame-bg.jpg");
00137       gc_set_background(gnome_canvas_root(gcomprisBoard->canvas),
00138                            img);
00139       g_free(img);
00140 
00141       /* set initial values for this level adjusted to fit the watch background */
00142       cx =  gcomprisBoard->width/2;
00143       cy =  gcomprisBoard->height*0.4 + 42;
00144       clock_size = gcomprisBoard->height*0.3;
00145 
00146       gcomprisBoard->level=1;
00147       gcomprisBoard->maxlevel=6;
00148       gcomprisBoard->sublevel=1;
00149       gcomprisBoard->number_of_sublevel=3; /* Go to next level after this number of 'play' */
00150       gc_score_start(SCORESTYLE_NOTE,
00151                         gcomprisBoard->width - 220,
00152                         gcomprisBoard->height - 50,
00153                         gcomprisBoard->number_of_sublevel);
00154       gc_bar_set(GC_BAR_LEVEL|GC_BAR_OK);
00155 
00156       clockgame_next_level();
00157 
00158       gamewon = FALSE;
00159       pause_board(FALSE);
00160 
00161       gc_cursor_set(GCOMPRIS_LINE_CURSOR);
00162     }
00163 
00164 }
00165 
00166 static void
00167 end_board ()
00168 {
00169 
00170   if(gcomprisBoard!=NULL)
00171     {
00172       pause_board(TRUE);
00173       gc_score_end();
00174       destroy_all_items();
00175     }
00176   gcomprisBoard = NULL;
00177   gc_cursor_set(GCOMPRIS_DEFAULT_CURSOR);
00178 }
00179 
00180 static void
00181 set_level (guint level)
00182 {
00183 
00184   if(gcomprisBoard!=NULL)
00185     {
00186       gcomprisBoard->level=level;
00187       gcomprisBoard->sublevel=1;
00188       clockgame_next_level();
00189     }
00190 }
00191 
00192 static gboolean
00193 is_our_board (GcomprisBoard *gcomprisBoard)
00194 {
00195   if (gcomprisBoard)
00196     {
00197       if(g_strcasecmp(gcomprisBoard->type, "clockgame")==0)
00198        {
00199          /* Set the plugin entry */
00200          gcomprisBoard->plugin=&menu_bp;
00201 
00202          return TRUE;
00203        }
00204     }
00205   return FALSE;
00206 }
00207 
00208 
00209 /*-------------------------------------------------------------------------------*/
00210 /*-------------------------------------------------------------------------------*/
00211 /*-------------------------------------------------------------------------------*/
00212 /*-------------------------------------------------------------------------------*/
00213 
00214 /* set initial values for the next level */
00215 static void clockgame_next_level()
00216 {
00217 
00218   gc_bar_set_level(gcomprisBoard);
00219   gc_score_set(gcomprisBoard->sublevel);
00220 
00221   destroy_all_items();
00222 
00223   /* Try the next level */
00224   get_random_hour(&timeToFind);
00225 
00226   /* Avoid to show up the solution directly */
00227   do {
00228     get_random_hour(&currentTime);
00229   } while(time_equal(&timeToFind, &currentTime));
00230 
00231   clockgame_create_item(gnome_canvas_root(gcomprisBoard->canvas));
00232 
00233 }
00234 
00235 /* ==================================== */
00236 /* Destroy all the items */
00237 static void
00238 destroy_all_items()
00239 {
00240 
00241   if(boardRootItem!=NULL)
00242     gtk_object_destroy (GTK_OBJECT(boardRootItem));
00243 
00244   boardRootItem = NULL;
00245 }
00246 
00247 
00248 static void display_digital_time(GnomeCanvasItem *item, GcomprisTime *time)
00249 {
00250   gchar *text = NULL;
00251   int temps;
00252 
00253   temps = (time->hour+12)*3600 + time->minute*60 + time->second;
00254   time->hour = (temps / 3600) % 12;
00255   time->minute = (temps / 60) % 60;
00256   time->second = temps % 60;
00257 
00258   if(item==NULL)
00259     return;
00260 
00261   if(gcomprisBoard->level<=2)
00262     text = g_strdup_printf("%.2d:%.2d", time->hour, time->minute);
00263   else
00264     text = g_strdup_printf("%.2d:%.2d:%.2d", time->hour, time->minute, time->second);
00265 
00266   gnome_canvas_item_set (item,
00267                       "text", text,
00268                       NULL);
00269   g_free(text);
00270 
00271 }
00272 
00273 static void display_hour(guint hour)
00274 {
00275   double needle_size = clock_size*0.70;
00276   double ang;
00277   GnomeCanvasPoints *canvasPoints;
00278 
00279   if(hour_item==NULL)
00280     return;
00281 
00282   /* Calc the needle angle */
00283   ang = ((hour > 12) ? hour-12 : hour) * M_PI / 6;
00284   ang += currentTime.minute * M_PI / 360;
00285   ang += currentTime.second * M_PI / 21600;
00286 
00287   canvasPoints = gnome_canvas_points_new (2);
00288   canvasPoints->coords[0]=cx;
00289   canvasPoints->coords[1]=cy;
00290   canvasPoints->coords[2]=cx + needle_size * sin(ang);
00291   canvasPoints->coords[3]=cy - needle_size * cos(ang);
00292   gnome_canvas_item_set (hour_item,
00293                       "points", canvasPoints,
00294                       "fill_color", "darkblue",
00295                       "width_units", (double)1,
00296                       "width_pixels", (guint) 4,
00297                       "last_arrowhead", TRUE,
00298                       "arrow_shape_a", (double) needle_size,
00299                       "arrow_shape_b", (double) needle_size-20,
00300                       "arrow_shape_c", (double) 8.0,
00301                       NULL);
00302   gnome_canvas_points_free(canvasPoints);
00303 
00304   currentTime.hour=hour;
00305   display_digital_time(digital_time_item, &currentTime);
00306   display_digital_time(digital_time_item_s, &currentTime);
00307 }
00308 
00309 static void display_minute(guint minute)
00310 {
00311   double needle_size = clock_size;
00312   double ang;
00313   GnomeCanvasPoints *canvasPoints;
00314 
00315   if(minute_item==NULL)
00316     return;
00317 
00318   ang = minute * M_PI / 30;
00319   ang += currentTime.second * M_PI / 1800;
00320 
00321   canvasPoints = gnome_canvas_points_new (2);
00322   canvasPoints->coords[0]=cx;
00323   canvasPoints->coords[1]=cy;
00324   canvasPoints->coords[2]=cx + needle_size * sin(ang);
00325   canvasPoints->coords[3]=cy - needle_size * cos(ang);
00326   gnome_canvas_item_set (minute_item,
00327                       "points", canvasPoints,
00328                       "fill_color", "red",
00329                       "width_units", (double)1,
00330                       "width_pixels", (guint) 4,
00331                       "last_arrowhead", TRUE,
00332                       "arrow_shape_a", (double) needle_size,
00333                       "arrow_shape_b", (double) needle_size-10,
00334                       "arrow_shape_c", (double) 3.0,
00335                       NULL);
00336   gnome_canvas_points_free(canvasPoints);
00337 
00338   currentTime.minute=minute;
00339   display_digital_time(digital_time_item, &currentTime);
00340   display_digital_time(digital_time_item_s, &currentTime);
00341 }
00342 
00343 static void display_second(guint second)
00344 {
00345   double needle_size = clock_size;
00346   double ang;
00347   GnomeCanvasPoints *canvasPoints;
00348 
00349   /* No seconds at first levels */
00350   if(second_item==NULL || gcomprisBoard->level<=2)
00351     return;
00352 
00353   ang = second * M_PI / 30;
00354 
00355   canvasPoints = gnome_canvas_points_new (2);
00356   canvasPoints->coords[0]=cx;
00357   canvasPoints->coords[1]=cy;
00358   canvasPoints->coords[2]=cx + needle_size * sin(ang);
00359   canvasPoints->coords[3]=cy - needle_size * cos(ang);
00360   gnome_canvas_item_set (second_item,
00361                       "points", canvasPoints,
00362                       "fill_color_rgba", 0x68c46fFF,
00363                       "width_units", (double)1,
00364                       "width_pixels", (guint) 4,
00365                       "last_arrowhead", TRUE,
00366                       "arrow_shape_a", (double) 0,
00367                       "arrow_shape_b", (double) 0,
00368                       "arrow_shape_c", (double) 0,
00369                       NULL);
00370   gnome_canvas_points_free(canvasPoints);
00371 
00372   currentTime.second=second;
00373   display_digital_time(digital_time_item, &currentTime);
00374   display_digital_time(digital_time_item_s, &currentTime);
00375 }
00376 
00377 
00378 static void
00379 clockgame_create_item(GnomeCanvasGroup *parent)
00380 {
00381   GnomeCanvasItem *item;
00382   double needle_size = clock_size;
00383   double min_point_size = clock_size*0.05;
00384   double hour_point_size = clock_size*0.1;
00385   double ang;
00386   guint min;
00387   GnomeCanvasPoints *canvasPoints;
00388   char *color;
00389   char *color_text;
00390   gchar *mtext = NULL;
00391   gchar *font = NULL;
00392 
00393   boardRootItem = GNOME_CANVAS_GROUP(
00394                                  gnome_canvas_item_new (gnome_canvas_root(gcomprisBoard->canvas),
00395                                                      gnome_canvas_group_get_type (),
00396                                                      "x", (double) 0,
00397                                                      "y", (double) 0,
00398                                                      NULL));
00399 
00400   canvasPoints = gnome_canvas_points_new (2);
00401 
00402   for(min = 1 ; min <= 60 ; min += 1)
00403     {
00404       ang = min * M_PI / 30;
00405       if(min%5==0)
00406        {
00407          /* Hour point */
00408          canvasPoints->coords[0]=cx + (needle_size-hour_point_size) * sin(ang);
00409          canvasPoints->coords[1]=cy - (needle_size-hour_point_size) * cos(ang);
00410          color="darkblue";
00411          color_text="red";
00412          font = gc_skin_font_board_small;
00413        }
00414       else
00415        {
00416          /* Minute point */
00417          canvasPoints->coords[0]=cx + (needle_size-min_point_size) * sin(ang);
00418          canvasPoints->coords[1]=cy - (needle_size-min_point_size) * cos(ang);
00419          color="red";
00420          color_text="red";
00421          font = gc_skin_font_board_tiny;
00422        }
00423 
00424       canvasPoints->coords[2]=cx + needle_size * sin(ang);
00425       canvasPoints->coords[3]=cy - needle_size * cos(ang);
00426       item = gnome_canvas_item_new (boardRootItem,
00427                                 gnome_canvas_line_get_type (),
00428                                 "points", canvasPoints,
00429                                 "fill_color", color,
00430                                 "width_units", (double)1,
00431                                 "width_pixels", (guint) 2,
00432                                 NULL);
00433 
00434       /* Display minute number */
00435       if(gcomprisBoard->level<5)
00436        {
00437          mtext = g_strdup_printf("%d", min);
00438          item = gnome_canvas_item_new (boardRootItem,
00439                                    gnome_canvas_text_get_type (),
00440                                    "text", mtext,
00441                                    "font", font,
00442                                    "x", (double) cx + (needle_size+10) * sin(ang),
00443                                    "y", (double) cy - (needle_size+10) * cos(ang),
00444                                    "anchor", GTK_ANCHOR_CENTER,
00445                                    "fill_color", color_text,
00446                                    "justification", GTK_JUSTIFY_CENTER,
00447                                    NULL);
00448          g_free(mtext);
00449        }
00450 
00451       /* Display hour numbers */
00452       if(gcomprisBoard->level<6)
00453        if(min%5==0)
00454          {
00455            mtext = g_strdup_printf( "%d", min/5);
00456            item = gnome_canvas_item_new (boardRootItem,
00457                                      gnome_canvas_text_get_type (),
00458                                      "text", mtext,
00459                                      "font", font,
00460                                      "x", (double) cx + (needle_size-30) * sin(ang),
00461                                      "y", (double) cy - (needle_size-30) * cos(ang),
00462                                      "anchor", GTK_ANCHOR_CENTER,
00463                                      "fill_color", "blue",
00464                                      "justification", GTK_JUSTIFY_CENTER,
00465                                      NULL);
00466            g_free(mtext);
00467          }
00468     }
00469 
00470   /* Create the text area for the digital time display */
00471   if(gcomprisBoard->level<4)
00472     {
00473       digital_time_item_s =
00474        gnome_canvas_item_new (boardRootItem,
00475                             gnome_canvas_text_get_type (),
00476                             "text", "",
00477                             "font", gc_skin_font_board_medium,
00478                             "x", (double) cx + 1.0,
00479                             "y", (double) cy +  needle_size/2 + 1.0,
00480                             "anchor", GTK_ANCHOR_CENTER,
00481                             "fill_color_rgba", 0xc4c4c4ff,
00482                             NULL);
00483       display_digital_time(digital_time_item_s, &currentTime);
00484 
00485       digital_time_item =
00486        gnome_canvas_item_new (boardRootItem,
00487                             gnome_canvas_text_get_type (),
00488                             "text", "",
00489                             "font", gc_skin_font_board_medium,
00490                             "x", (double) cx,
00491                             "y", (double) cy +  needle_size/2,
00492                             "anchor", GTK_ANCHOR_CENTER,
00493                             "fill_color", "blue",
00494                             NULL);
00495       display_digital_time(digital_time_item, &currentTime);
00496     }
00497   else
00498     {
00499       digital_time_item_s = NULL;
00500       digital_time_item = NULL;
00501     }
00502 
00503   /* Create the Hour needle */
00504 
00505   canvasPoints->coords[0]=0;
00506   canvasPoints->coords[1]=0;
00507   canvasPoints->coords[2]=0;
00508   canvasPoints->coords[3]=0;
00509   hour_item = gnome_canvas_item_new (boardRootItem,
00510                                  gnome_canvas_line_get_type (),
00511                                  "points", canvasPoints,
00512                                  "fill_color", "darkblue",
00513                                  "width_units", (double)1,
00514                                  "width_pixels", (guint) 0,
00515                                  NULL);
00516   gtk_signal_connect(GTK_OBJECT(hour_item), "event",
00517                    (GtkSignalFunc) item_event,
00518                    NULL);
00519   display_hour(currentTime.hour);
00520 
00521   /* Create the minute needle */
00522 
00523   minute_item = gnome_canvas_item_new (boardRootItem,
00524                                    gnome_canvas_line_get_type (),
00525                                    "points", canvasPoints,
00526                                    "fill_color", "darkblue",
00527                                    "width_units", (double)1,
00528                                    "width_pixels", (guint) 0,
00529                                    NULL);
00530   gtk_signal_connect(GTK_OBJECT(minute_item), "event",
00531                    (GtkSignalFunc) item_event,
00532                    NULL);
00533   display_minute(currentTime.minute);
00534 
00535   /* Create the second needle */
00536 
00537   second_item = gnome_canvas_item_new (boardRootItem,
00538                                    gnome_canvas_line_get_type (),
00539                                    "points", canvasPoints,
00540                                    "fill_color", "darkblue",
00541                                    "width_units", (double)1,
00542                                    "width_pixels", (guint) 0,
00543                                    NULL);
00544   gtk_signal_connect(GTK_OBJECT(second_item), "event",
00545                    (GtkSignalFunc) item_event,
00546                    NULL);
00547   display_second(currentTime.second);
00548 
00549   /* Create the text area for the time to find display */
00550   gnome_canvas_item_new (boardRootItem,
00551                       gnome_canvas_text_get_type (),
00552                       "text", _("Set the watch to:"),
00553                       "font", gc_skin_font_board_small,
00554                       "x", (double) gcomprisBoard->width*0.17 + 1.0,
00555                       "y", (double) cy + needle_size +  needle_size / 3 - 30 + 1.0,
00556                       "anchor", GTK_ANCHOR_CENTER,
00557                       "fill_color_rgba", gc_skin_color_shadow,
00558                       NULL);
00559 
00560   gnome_canvas_item_new (boardRootItem,
00561                       gnome_canvas_text_get_type (),
00562                       "text", _("Set the watch to:"),
00563                       "font", gc_skin_font_board_small,
00564                       "x", (double) gcomprisBoard->width*0.17,
00565                       "y", (double) cy + needle_size +  needle_size / 3 - 30,
00566                       "anchor", GTK_ANCHOR_CENTER,
00567                       "fill_color_rgba", gc_skin_get_color("clockgame/text"),
00568                       NULL);
00569 
00570   time_to_find_item_s =
00571     gnome_canvas_item_new (boardRootItem,
00572                         gnome_canvas_text_get_type (),
00573                         "text", "",
00574                         "font", gc_skin_font_board_big_bold,
00575                         "x", (double) gcomprisBoard->width*0.17 + 1.0,
00576                         "y", (double) cy + needle_size +  needle_size / 3 + 1.0,
00577                         "anchor", GTK_ANCHOR_CENTER,
00578                         "fill_color_rgba", gc_skin_color_shadow,
00579                         NULL);
00580   display_digital_time(time_to_find_item_s, &timeToFind);
00581 
00582   time_to_find_item =
00583     gnome_canvas_item_new (boardRootItem,
00584                         gnome_canvas_text_get_type (),
00585                         "text", "",
00586                         "font", gc_skin_font_board_big_bold,
00587                         "x", (double) gcomprisBoard->width*0.17,
00588                         "y", (double) cy + needle_size +  needle_size / 3,
00589                         "anchor", GTK_ANCHOR_CENTER,
00590                         "fill_color_rgba", gc_skin_get_color("clockgame/text"),
00591                         NULL);
00592   display_digital_time(time_to_find_item, &timeToFind);
00593 
00594   gnome_canvas_points_free(canvasPoints);
00595 
00596 }
00597 
00598 /*
00599  * Returns true is given times are equal
00600  */
00601 static gboolean
00602 time_equal(GcomprisTime *time1, GcomprisTime *time2)
00603 {
00604   /* No seconds at first levels */
00605   if(second_item==NULL || gcomprisBoard->level<=2)
00606     return(time1->hour==time2->hour
00607           &&time1->minute==time2->minute);
00608   else
00609     return(time1->hour==time2->hour
00610           &&time1->minute==time2->minute
00611           &&time1->second==time2->second);
00612 
00613 }
00614 
00615 /* ==================================== */
00616 static void game_won()
00617 {
00618   gamewon = FALSE;
00619   gcomprisBoard->sublevel++;
00620 
00621   if(gcomprisBoard->sublevel>gcomprisBoard->number_of_sublevel) {
00622     /* Try the next level */
00623     gcomprisBoard->sublevel=1;
00624     gcomprisBoard->level++;
00625     if(gcomprisBoard->level>gcomprisBoard->maxlevel) { // the current board is finished : bail out
00626       gc_bonus_end_display(BOARD_FINISHED_RANDOM);
00627       return;
00628     }
00629     gc_sound_play_ogg ("sounds/bonus.ogg", NULL);
00630   }
00631   clockgame_next_level();
00632 }
00633 
00634 /* ==================================== */
00635 static void process_ok()
00636 {
00637   if(time_equal(&timeToFind, &currentTime))
00638     {
00639       gamewon = TRUE;
00640     }
00641   else
00642     {
00643       /* Oups, you're wrong */
00644       gamewon = FALSE;
00645     }
00646   gc_bonus_display(gamewon, BONUS_FLOWER);
00647 }
00648 
00649 
00650 /* Callback for the 'toBeFoundItem' */
00651 static gint
00652 item_event(GnomeCanvasItem *item, GdkEvent *event, gpointer data)
00653 {
00654   static double x, y;
00655   double item_x, item_y;
00656   static int dragging;
00657   GdkCursor *fleur;
00658   double new_x, new_y;
00659 
00660   if(board_paused)
00661     return FALSE;
00662 
00663   item_x = event->button.x;
00664   item_y = event->button.y;
00665   gnome_canvas_item_w2i(item->parent, &item_x, &item_y);
00666 
00667   switch (event->type)
00668     {
00669     case GDK_BUTTON_PRESS:
00670       x = item_x;
00671       y = item_y;
00672 
00673       fleur = gdk_cursor_new(GDK_FLEUR);
00674       gc_canvas_item_grab(item,
00675                           GDK_POINTER_MOTION_MASK |
00676                           GDK_BUTTON_RELEASE_MASK,
00677                           fleur,
00678                           event->button.time);
00679       gdk_cursor_destroy(fleur);
00680       dragging = TRUE;
00681       break;
00682 
00683     case GDK_MOTION_NOTIFY:
00684       if (dragging && (event->motion.state & GDK_BUTTON1_MASK))
00685        {
00686 
00687           double angle;
00688 
00689           /* only use coords relative to the center, with standard
00690              direction for axis (y's need to be negated for this) */
00691           new_x = item_x - cx;
00692           new_y = - item_y + cy;
00693 
00694           /* angle as mesured relatively to noon position */
00695          /* Thanks to Martin Herweg for this code        */
00696          angle =  atan2(new_x,new_y);
00697          if (angle<0) {angle= angle + 2.0*M_PI;}
00698 
00699          if(item==hour_item)
00700            display_hour(angle * 6 / M_PI);
00701          else if(item==minute_item)
00702          {
00703            if(currentTime.minute > 45 && angle * 30 / M_PI < 15)
00704              currentTime.hour++;
00705 
00706            if(currentTime.minute < 15 && angle * 30 / M_PI > 45)
00707              currentTime.hour--;
00708 
00709            display_minute(angle * 30 / M_PI);
00710            display_hour(currentTime.hour);
00711          }
00712          else if(item==second_item)
00713          {
00714            if(currentTime.second > 45 && angle * 30 / M_PI < 15)
00715              currentTime.minute++;
00716 
00717            if(currentTime.second < 15 && angle * 30 / M_PI > 45)
00718              currentTime.minute--;
00719 
00720            display_second(angle * 30 / M_PI);
00721            display_minute(currentTime.minute);
00722            display_hour(currentTime.hour);
00723          }
00724 
00725           x = new_x + cx;
00726           y = new_y + cy;
00727        }
00728       break;
00729 
00730     case GDK_BUTTON_RELEASE:
00731       if(dragging)
00732        {
00733          gc_canvas_item_ungrab(item, event->button.time);
00734          dragging = FALSE;
00735        }
00736       break;
00737 
00738     default:
00739       break;
00740     }
00741   return FALSE;
00742 }
00743 
00744 
00745 /* Returns a random time based on the current level */
00746 static void get_random_hour(GcomprisTime *time)
00747 {
00748 
00749   time->hour=rand()%12;
00750 
00751   if(gcomprisBoard->level>3)
00752     time->second=rand()%60;
00753   else time->second=0;
00754 
00755   time->minute=rand()%60;
00756 
00757   switch(gcomprisBoard->level)
00758     {
00759     case 1:
00760       time->minute=rand()%4*15;
00761       break;
00762     case 2:
00763       time->minute=rand()%12*5;
00764       break;
00765     default:
00766       break;
00767     }
00768 
00769 }