Prep for 0.9.3 release.
[stopish] / src / stopish.c
index e44879d..af7a7da 100644 (file)
@@ -1,6 +1,6 @@
 //      stopish.c
 //
-//      Copyright 2009 Michael Cronenworth <mike@cchtml.com>
+//      Copyright 2010 Michael Cronenworth <mike@cchtml.com>
 //
 //      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
@@ -21,7 +21,6 @@
 #include <stdlib.h>
 #include <sys/time.h>
 #include <gtk/gtk.h>
-#include <libosso.h>
 #include <hildon/hildon.h>
 #include <dbus/dbus.h>
 #include <mce/mode-names.h>
 typedef struct _AppData AppData;
 struct _AppData {
     GtkWindow *main_window;
+    GtkWindow *countdown_window;
     osso_context_t *osso_context;
     DBusConnection *system_bus;
 };
 
+
 static AppData appdata;
-static GtkWidget *timerLabel = NULL;
-static GtkWidget *timerHistoryLabel1 = NULL;
-static GtkWidget *timerHistoryLabel2 = NULL;
-static GtkWidget *timerHistoryLabel3 = NULL;
-static GtkWidget *timerHistoryLabel4 = NULL;
-static GSList *historyList = NULL;
 static int stopishMode = STOPISH_MODE_START;
-static int timerHandle = -1;
+static int stopishOrientation = STOPISH_LANDSCAPE;
+static int stopishType = STOPISH_TYPE_STOPWATCH;
+
 
 //Prototypes
 gint dbus_callback( const gchar *interface, const gchar *method,
                        GArray *arguments, gpointer data, osso_rpc_t *retval );
-static GtkWindow *stopish_new( void );
-static void start_cb( GtkButton* button, gpointer data );
-static void reset_cb( GtkButton* button, gpointer data );
+static void main_menu( GtkWindow *window );
+static void change_type_cb( GtkButton* button, gpointer data );
 static void close_cb( GtkButton* button, gpointer data );
-static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event,
-                             gpointer data );
-static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
-                              gpointer data );
 static void accelerometer_enable( void );
 static void accelerometer_disable( void );
 static DBusHandlerResult mce_filter_func( DBusConnection * connection,
@@ -85,7 +77,19 @@ int main( int argc, char *argv[] )
     program = hildon_program_get_instance(  );
 
     // create main window
-    appdata.main_window = stopish_new(  );
+    appdata.main_window = stopish_stopwatch_new(  );
+
+    // attach signals to main window
+    g_signal_connect( G_OBJECT( appdata.main_window ), "destroy",
+                      G_CALLBACK( close_cb ), appdata.main_window );
+    g_signal_connect( G_OBJECT( appdata.main_window ), "focus-in-event",
+                      G_CALLBACK( stopish_focus_in_cb ), NULL );
+    g_signal_connect( G_OBJECT( appdata.main_window ), "focus-out-event",
+                      G_CALLBACK( stopish_focus_out_cb ), NULL );
+
+    // setup main menu
+    main_menu( appdata.main_window );
+
     hildon_program_add_window( program, HILDON_WINDOW( appdata.main_window ) );
 
     // Connect to session bus, add a match rule, install filter callback
@@ -126,220 +130,142 @@ gint dbus_callback( const gchar *interface, const gchar *method,
 }
 
 
-int stopish_get_mode( void )
+void stopish_about_cb( GtkButton* button, gpointer data )
 {
-    return stopishMode;
+    GdkPixbuf *logo;
+    GError *error;
+    GtkWidget *dialog;
+    char *authors[2];
+
+    authors[0] = strdup( "Michael Cronenworth" );
+    authors[1] = NULL;
+
+    dialog = gtk_about_dialog_new(  );
+
+    gtk_about_dialog_set_program_name( GTK_ABOUT_DIALOG( dialog ),
+                                       "Stopish" );
+    gtk_about_dialog_set_version( GTK_ABOUT_DIALOG( dialog ),
+                                  STOPISH_VERSION_STR );
+    gtk_about_dialog_set_authors( GTK_ABOUT_DIALOG( dialog ),
+                                  ( const char ** ) authors );
+    logo = gdk_pixbuf_new_from_file( "/usr/share/icons/hicolor/40x40/hildon/stopish.png",
+                                     &error );
+    gtk_about_dialog_set_logo( GTK_ABOUT_DIALOG( dialog ),
+                               logo );
+
+    gtk_dialog_run( GTK_DIALOG( dialog ) );
+
+    gtk_widget_destroy( dialog );
+    free( authors[0] );
 }
 
 
-static GtkWindow *stopish_new( void )
+int stopish_get_mode( void )
 {
-    GtkWidget *window, *button, *button0, *label;
-    GtkWidget *vBoxMain, *vBox0, *hBox0;
+    return stopishMode;
+}
 
-    window = hildon_stackable_window_new(  );
 
-    gtk_container_set_border_width( GTK_CONTAINER( window ), 20 );
+void stopish_set_mode( int newMode )
+{
+    stopishMode = newMode;
+}
 
-    gtk_window_set_title( GTK_WINDOW( window ), "Stopish" );
 
-    // attach signals to main window
-    g_signal_connect( G_OBJECT( window ), "destroy",
-                      G_CALLBACK( close_cb ), window );
-    g_signal_connect( G_OBJECT( window ), "focus-in-event",
-                      G_CALLBACK( focus_in_cb ), NULL );
-    g_signal_connect( G_OBJECT( window ), "focus-out-event",
-                      G_CALLBACK( focus_out_cb ), NULL );
-
-    vBoxMain = gtk_vbox_new( FALSE, 10 );
-
-    // separator
-    label = gtk_label_new( NULL );
-    gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
-
-    // stop watch area
-    vBox0 = gtk_vbox_new( FALSE, 5 );
-
-    // main timer
-    timerLabel = gtk_label_new( NULL );
-    gtk_label_set_markup( GTK_LABEL( timerLabel ),
-                          "<span font_family=\"monospace\" "
-                          "size=\"70000\" weight=\"ultrabold\">"
-                          "00:00:00.0</span>" );
-    gtk_container_add( GTK_CONTAINER( vBox0 ), timerLabel );
-
-    // history area
-    timerHistoryLabel1 = gtk_label_new( NULL );
-    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
-                          "<span size=\"large\"> </span>" );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel1, FALSE, FALSE, 0 );
-    timerHistoryLabel2 = gtk_label_new( NULL );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel2, FALSE, FALSE, 0 );
-    timerHistoryLabel3 = gtk_label_new( NULL );
-    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ),
-                          "<span size=\"small\"> </span>" );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 );
-    timerHistoryLabel4 = gtk_label_new( NULL );
-    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
-                          "<span size=\"x-small\"> </span>" );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel4, FALSE, FALSE, 0 );
-
-    gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 );
-
-    // separator
-    label = gtk_label_new( NULL );
-    gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
-
-    // button area
-    hBox0 = gtk_hbox_new( FALSE, 15 );
-    gtk_widget_set_size_request( hBox0, -1, 80 );
-
-    // start/pause stopwatch button
-    button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
-                                          HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
-                                          "Start", NULL );
-    button0 = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
-                                           HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
-                                           "Reset", NULL );
-    g_signal_connect( G_OBJECT( button ), "clicked",
-                      G_CALLBACK( start_cb ), button0 );
-    gtk_container_add( GTK_CONTAINER( hBox0 ), button );
-
-    // reset button
-    gtk_widget_set_sensitive( button0, FALSE );
-    g_signal_connect( G_OBJECT( button0 ), "clicked",
-                      G_CALLBACK( reset_cb ), button );
-    gtk_container_add( GTK_CONTAINER( hBox0 ), button0 );
-
-    gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 );
-
-    gtk_container_add( GTK_CONTAINER( window ), vBoxMain );
-
-    gtk_widget_show_all( window );
-
-    return GTK_WINDOW( window );
+int stopish_get_type( void )
+{
+    return stopishType;
 }
 
 
-static void start_cb( GtkButton* button, gpointer data )
+void stopish_set_type( int newType )
 {
-    if ( stopishMode == STOPISH_MODE_START ) {
-        // set label text and add timer handle
-        gtk_button_set_label( button, "Pause" );
-        stopishMode = STOPISH_MODE_PAUSE;
-        stopish_set_time_start( stopish_current_time(  ) );
-        timerHandle = g_timeout_add( 100, stopish_timeout_cb, timerLabel );
-    }
-    else if ( stopishMode == STOPISH_MODE_RESUME ) {
-        // resume timer
-        gtk_button_set_label( button, "Pause" );
-        stopishMode = STOPISH_MODE_PAUSE;
-        stopish_timer_resume(  );
-        timerHandle = g_timeout_add( 100, stopish_timeout_cb, timerLabel );
-    }
-    else {
-        // pause timer, remove timeout
-        gtk_button_set_label( button, "Resume" );
-        stopishMode = STOPISH_MODE_RESUME;
-        g_source_remove( timerHandle );
-        stopish_timer_save(  );
-    }
-
-    // allow user to reset timer
-    gtk_widget_set_sensitive( GTK_WIDGET( data ), TRUE );
+    stopishType = newType;
 }
 
 
-static void reset_cb( GtkButton* button, gpointer data )
+int stopish_get_orientation( void )
 {
-    GSList *tempList;
-    char *tempString;
-    char formatString[128];
-
-    if ( stopishMode == STOPISH_MODE_RESUME )
-        stopish_timer_resume(  );
-
-    // set label text and remove timer handle
-    gtk_button_set_label( GTK_BUTTON( data ), "Start" );
-    stopishMode = STOPISH_MODE_START;
-    gtk_label_set_markup( GTK_LABEL( timerLabel ),
-                          "<span font_family=\"monospace\" "
-                          "size=\"70000\" weight=\"ultrabold\">"
-                          "00:00:00.0</span>" );
-    g_source_remove( timerHandle );
-
-    // add current time to history
-    historyList = g_slist_prepend( historyList,
-                                   ( gpointer ) stopish_get_time_string(  ) );
-    sprintf( formatString, "<span size=\"large\">%s</span>",
-             ( char * ) historyList->data );
-    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
-                          formatString );
-    tempList = historyList;
-    tempList = g_slist_next( tempList );
-    if ( tempList ) {
-        gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ),
-                            ( char * ) tempList->data );
-    }
-    tempList = g_slist_next( tempList );
-    if ( tempList ) {
-        sprintf( formatString, "<span size=\"small\">%s</span>",
-                 ( char * ) tempList->data );
-        gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ),
-                              formatString );
-    }
-    tempList = g_slist_next( tempList );
-    if ( tempList ) {
-        sprintf( formatString, "<span size=\"x-small\">%s</span>",
-                 ( char * ) tempList->data );
-        gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
-                              formatString );
-    }
+    return stopishOrientation;
+}
 
-    // remove the history time after the 4th
-    tempList = g_slist_next( tempList );
-    if ( tempList ) {
-        tempString = tempList->data;
-        historyList = g_slist_remove( historyList, tempList->data );
-        free( tempString );
-    }
 
-    // reset start time
-    stopish_set_time_start( 0 );
+gboolean stopish_focus_in_cb( GtkWidget *widget, GdkEventFocus *event,
+                              gpointer data )
+{
+    // enable accelerometer hardware for portrait mode support
+    accelerometer_enable(  );
 
-    // disallow user to reset timer
-    gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
+    return FALSE;
 }
 
 
-static void close_cb( GtkButton* button, gpointer data )
+gboolean stopish_focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
+                               gpointer data )
 {
     // disable accelerometer for battery savings
     accelerometer_disable(  );
 
-    // destroy main window and exit gtk main loop
-    gtk_widget_destroy( GTK_WIDGET( data ) );
-    gtk_main_quit(  );
+    return FALSE;
 }
 
 
-static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event,
-                             gpointer data )
+static void main_menu( GtkWindow *window )
 {
-    // enable accelerometer hardware for portrait mode support
-    accelerometer_enable(  );
+    HildonAppMenu *menu;
+    GtkWidget *button, *radio;
 
-    return FALSE;
+    menu = ( HildonAppMenu * ) hildon_app_menu_new(  );
+
+    button = gtk_button_new_with_label( "Countdown" );
+    g_signal_connect_after( G_OBJECT( button ), "clicked",
+                            G_CALLBACK( change_type_cb ), NULL );
+    hildon_app_menu_append( menu, GTK_BUTTON( button ) );
+
+    button = gtk_button_new_with_label( "About" );
+    g_signal_connect_after( G_OBJECT( button ), "clicked",
+                            G_CALLBACK( stopish_about_cb ), NULL );
+    hildon_app_menu_append( menu, GTK_BUTTON( button ) );
+
+    // Hour preference
+    radio = gtk_radio_button_new_with_label( NULL, "Hour" );
+    gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON( radio ), FALSE );
+    g_signal_connect_after( G_OBJECT( radio ), "clicked",
+                            G_CALLBACK( stopish_stopwatch_perf_timer_hour ), NULL );
+    hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
+
+    // Minute preference
+    radio = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radio ), "Minute" );
+    gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON ( radio ), FALSE );
+    g_signal_connect_after( G_OBJECT( radio ), "clicked",
+                            G_CALLBACK( stopish_stopwatch_perf_timer_minute ), NULL );
+    hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
+
+    // default to minute
+    gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radio ), TRUE );
+
+    gtk_widget_show_all( GTK_WIDGET( menu ) );
+
+    hildon_window_set_app_menu( HILDON_WINDOW( window ), menu );
 }
 
 
-static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
-                              gpointer data )
+static void change_type_cb( GtkButton* button, gpointer data )
+{
+    stopish_stopwatch_reset(  );
+    stopishType = STOPISH_TYPE_COUNTDOWN;
+    stopish_countdown_new(  );
+}
+
+
+static void close_cb( GtkButton* button, gpointer data )
 {
     // disable accelerometer for battery savings
     accelerometer_disable(  );
 
-    return FALSE;
+    // destroy main window and exit gtk main loop
+    gtk_widget_destroy( GTK_WIDGET( data ) );
+    gtk_main_quit(  );
 }
 
 
@@ -379,12 +305,24 @@ static DBusHandlerResult mce_filter_func( DBusConnection * connection,
             dbus_message_iter_get_basic( &iter, &rotation );
 
             // Rotate main window
-            if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) )
+            if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) ) {
                 hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
                                                       HILDON_PORTRAIT_MODE_REQUEST );
-            else
+                if ( stopishType == STOPISH_TYPE_STOPWATCH )
+                    stopish_stopwatch_label_timer_portrait(  );
+                else
+                    stopish_countdown_label_timer_portrait(  );
+                stopishOrientation = STOPISH_PORTRAIT;
+            }
+            else {
                 hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
                                                       ~HILDON_PORTRAIT_MODE_REQUEST );
+                if ( stopishType == STOPISH_TYPE_STOPWATCH )
+                    stopish_stopwatch_label_timer_landscape(  );
+                else
+                    stopish_countdown_label_timer_landscape(  );
+                stopishOrientation = STOPISH_LANDSCAPE;
+            }
         }
         else
             g_printerr( "ERROR: dbus_message_iter_init() failed.\n" );