Implement more functionality:
authorMichael Cronenworth <michael@melchior.(none)>
Thu, 10 Dec 2009 04:06:16 +0000 (22:06 -0600)
committerMichael Cronenworth <michael@melchior.(none)>
Thu, 10 Dec 2009 04:06:16 +0000 (22:06 -0600)
 - Start, pause, and resume.
 - Reset button.
 - Timer history.

src/Makefile.am
src/stopish.c
src/stopish.h [new file with mode: 0644]
src/timer.c [new file with mode: 0644]

index 9d7cd3d..a6989ef 100644 (file)
@@ -8,7 +8,7 @@
 
 bin_PROGRAMS = stopish
 
-stopish_SOURCES = stopish.c
+stopish_SOURCES = stopish.c stopish.h timer.c
 
 stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS)
 stopish_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(DESKTOP_LIBS)
index c1fd229..a201cd4 100644 (file)
 //      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 //      MA 02110-1301, USA.
 
-
 #include <string.h>
 #include <stdlib.h>
 #include <sys/time.h>
-
 #include <gtk/gtk.h>
 #include <libosso.h>
 
+#include "stopish.h"
+
 static GtkWidget *timerLabel = NULL;
-static int stopishMode = 0; // 0 = Start, 1 = Stop
+static GtkWidget *timerHistoryLabel1 = NULL;
+static GtkWidget *timerHistoryLabel2 = NULL;
+static GtkWidget *timerHistoryLabel3 = NULL;
+static GSList *historyList = NULL;
+static int stopishMode = STOPISH_MODE_START;
 static int timerHandle = -1;
-static int timerStartTime = 0;
-static int timeTicks = 0;
 
 //Prototypes
 gint dbus_callback( const gchar *interface, const gchar *method,
                        GArray *arguments, gpointer data, osso_rpc_t *retval );
-GtkWindow *stopish_new( void );
+static GtkWindow *stopish_new( void );
 static void start_cb( GtkButton* button, gpointer data );
+static void reset_cb( GtkButton* button, gpointer data );
 static void close_cb( GtkButton* button, gpointer data );
-static gint timeout_cb( gpointer data );
-static int current_time( void );
 
 
 int main( int argc, char *argv[] )
@@ -85,10 +86,16 @@ gint dbus_callback( const gchar *interface, const gchar *method,
 }
 
 
-GtkWindow *stopish_new( void )
+int stopish_get_mode( void )
+{
+    return stopishMode;
+}
+
+
+static GtkWindow *stopish_new( void )
 {
-    GtkWidget *window, *hBox, *label, *button;
-    GtkWidget *vBox, *vBox0;
+    GtkWidget *window, *hBox, *label, *button, *button0;
+    GtkWidget *vBox, *vBox0, *vBox1;
 
     window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
 
@@ -99,7 +106,7 @@ GtkWindow *stopish_new( void )
     g_signal_connect( G_OBJECT( window ), "destroy",
                       G_CALLBACK( close_cb ), window );
 
-    vBox = gtk_vbox_new( FALSE, 10 );
+    vBox = gtk_vbox_new( FALSE, 20 );
 
     label = gtk_label_new( "Stopish - The Stopwatch" );
     gtk_box_pack_start( GTK_BOX( vBox ), label, FALSE, FALSE, 0 );
@@ -107,28 +114,47 @@ GtkWindow *stopish_new( void )
     hBox = gtk_hbox_new( FALSE, 10 );
 
     // stop watch area
+    vBox0 = gtk_vbox_new( FALSE, 5 );
+    gtk_widget_set_size_request( vBox0, 250, -1 );
+
+    // main timer
     timerLabel = gtk_label_new( NULL );
-    gtk_label_set_markup( GTK_LABEL( timerLabel ), "<big>00:00:00.0</big>" );
-    gtk_container_add( GTK_CONTAINER( hBox ), timerLabel );
+    gtk_label_set_markup( GTK_LABEL( timerLabel ),
+                          "<span font_family=\"monospace\" size=\"xx-large\">00:00:00.0</span>" );
+    gtk_container_add( GTK_CONTAINER( vBox0 ), timerLabel );
+
+    // history area
+    timerHistoryLabel1 = gtk_label_new( NULL );
+    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_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 );
+    label = gtk_label_new( NULL );
+    gtk_container_add( GTK_CONTAINER( vBox0 ), label );
+
+    gtk_container_add( GTK_CONTAINER( hBox ), vBox0 );
 
     // button area
-    vBox0 = gtk_vbox_new( FALSE, 10 );
+    vBox1 = gtk_vbox_new( FALSE, 15 );
+    gtk_widget_set_size_request( vBox1, 200, -1 );
 
-    // close button
-    button = gtk_button_new(  );
-    label = gtk_label_new( "Start" );
-    gtk_container_add( GTK_CONTAINER( button ), label );
+    // start/pause stopwatch button
+    button = gtk_button_new_with_label( "Start" );
+    button0 = gtk_button_new_with_label( "Reset" );
+    gtk_widget_set_size_request( button, -1, 60 );
     g_signal_connect( G_OBJECT( button ), "clicked",
-                      G_CALLBACK( start_cb ), label );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), button, FALSE, FALSE, 0 );
+                      G_CALLBACK( start_cb ), button0 );
+    gtk_box_pack_start( GTK_BOX( vBox1 ), button, FALSE, FALSE, 0 );
 
-    // start stopwatch button
-    button = gtk_button_new_with_label( "Close" );
-    g_signal_connect( G_OBJECT( button ), "clicked",
-                      G_CALLBACK( close_cb ), window );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), button, FALSE, FALSE, 0 );
+    // reset button
+    gtk_widget_set_sensitive( button0, FALSE );
+    gtk_widget_set_size_request( button0, -1, 60 );
+    g_signal_connect( G_OBJECT( button0 ), "clicked",
+                      G_CALLBACK( reset_cb ), button );
+    gtk_box_pack_start( GTK_BOX( vBox1 ), button0, FALSE, FALSE, 0 );
 
-    gtk_container_add( GTK_CONTAINER( hBox ), vBox0 );
+    gtk_container_add( GTK_CONTAINER( hBox ), vBox1 );
 
     gtk_container_add( GTK_CONTAINER( vBox ), hBox );
 
@@ -142,67 +168,82 @@ GtkWindow *stopish_new( void )
 
 static void start_cb( GtkButton* button, gpointer data )
 {
-    if ( stopishMode == 0 ) {
+    if ( stopishMode == STOPISH_MODE_START ) {
         // set label text and add timer handle
-        gtk_label_set_text( GTK_LABEL( data ), "Stop" );
-        stopishMode = 1;
-        timerHandle = g_timeout_add( 100, timeout_cb, NULL );
-        timerStartTime = current_time(  ) - timeTicks;
+        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 {
-        // set label text and remove timer handle
-        gtk_label_set_text( GTK_LABEL( data ), "Start" );
-        stopishMode = 0;
-        timerStartTime = 0;
-        timeTicks = 0;
-        gtk_label_set_markup( GTK_LABEL( timerLabel ),
-                              "<big>00:00:00.0</big>" );
+        // 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 );
 }
 
 
-static void close_cb( GtkButton* button, gpointer data )
+static void reset_cb( GtkButton* button, gpointer data )
 {
-    // destroy main window and exit gtk main loop
-    gtk_widget_destroy( GTK_WIDGET( data ) );
-    gtk_main_quit(  );
-}
+    GSList *tempList;
+    char *tempString;
+
+    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=\"xx-large\">00:00:00.0</span>" );
+    g_source_remove( timerHandle );
+
+    // add current time to history
+    historyList = g_slist_prepend( historyList,
+                                   ( gpointer ) stopish_get_time_string(  ) );
+    gtk_label_set_text( GTK_LABEL( timerHistoryLabel1 ),
+                        ( char * ) historyList->data );
+    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 )
+        gtk_label_set_text( GTK_LABEL( timerHistoryLabel3 ),
+                            ( char * ) tempList->data );
+
+    // remove the history time after the 3rd
+    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 );
 
-static gint timeout_cb( gpointer data )
-{
-    static char timeBuffer[64];
-    int h, m, s, ss, currentTime;
-
-    // get current time
-    currentTime = current_time(  );
-
-    // calculate time format
-    timeTicks = ( currentTime - timerStartTime );
-    ss = timeTicks % 10;
-    s = timeTicks / 10;
-    m = s / 60;
-    s = s % 60;
-    h = m / 60;
-    m = m % 60;
-
-    // print to screen
-    sprintf( timeBuffer, "<big>%.02d:%.02d:%.02d.%.1d</big>", h, m, s, ss);
-    gtk_label_set_markup( GTK_LABEL( timerLabel ), timeBuffer );
-
-    return TRUE;
+    // disallow user to reset timer
+    gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
 }
 
 
-static int current_time( void )
+static void close_cb( GtkButton* button, gpointer data )
 {
-    struct timeval tv;
-    int s, us;
-
-    gettimeofday( &tv, NULL );
-    s = tv.tv_sec % 100000;
-    us = tv.tv_usec / 100000;
-
-    return ( s * 10 + us );
+    // destroy main window and exit gtk main loop
+    gtk_widget_destroy( GTK_WIDGET( data ) );
+    gtk_main_quit(  );
 }
diff --git a/src/stopish.h b/src/stopish.h
new file mode 100644 (file)
index 0000000..986e3ae
--- /dev/null
@@ -0,0 +1,42 @@
+//      stopish.h
+//
+//      Copyright 2009 Michael Cronenworth <michael@melchior>
+//
+//      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 2 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, write to the Free Software
+//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+//      MA 02110-1301, USA.
+
+
+#ifndef __STOPISH_H__
+#define __STOPISH_H__
+
+#define STOPISH_MODE_START  0
+#define STOPISH_MODE_PAUSE  1
+#define STOPISH_MODE_RESUME 2
+
+// stopish.c
+gint dbus_callback( const gchar *interface, const gchar *method,
+                       GArray *arguments, gpointer data, osso_rpc_t *retval );
+int stopish_get_mode( void );
+
+// timer.c
+gint stopish_timeout_cb( gpointer data );
+char *stopish_get_time_string( void );
+long int stopish_get_time_timer( void );
+void stopish_set_time_start( long int time );
+void stopish_timer_resume( void );
+void stopish_timer_save( void );
+long int stopish_current_time( void );
+
+#endif
diff --git a/src/timer.c b/src/timer.c
new file mode 100644 (file)
index 0000000..ca1c41d
--- /dev/null
@@ -0,0 +1,119 @@
+//      timer.c
+//
+//      Copyright 2009 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
+//      the Free Software Foundation; either version 2 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, write to the Free Software
+//      Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+//      MA 02110-1301, USA.
+
+#include <string.h>
+#include <stdlib.h>
+#include <sys/time.h>
+#include <gtk/gtk.h>
+#include <libosso.h>
+
+#include "stopish.h"
+
+static long int timerStartTime = 0;
+static long int timerSave = 0;
+
+
+//
+// Timer callback
+//
+gint stopish_timeout_cb( gpointer data )
+{
+    GtkLabel *timerLabel;
+    char formatBuffer[64];
+    char *tempString;
+
+    if ( !data )
+        return -1;
+
+    timerLabel = ( GtkLabel * ) data;
+
+    // print to screen
+    tempString = stopish_get_time_string(  );
+    sprintf( formatBuffer, "<span font_family=\"monospace\" size=\"xx-large\">%s</span>", tempString );
+    free( tempString );
+    gtk_label_set_markup( GTK_LABEL( timerLabel ), formatBuffer );
+
+    return TRUE;
+}
+
+
+char *stopish_get_time_string( void )
+{
+    char *timeBuffer;
+    long int currentTime;
+    int h, m, s, ss;
+
+    // get current time
+    currentTime = stopish_current_time(  );
+
+    // calculate time format
+    ss = ( currentTime - timerStartTime ) % 10;
+    s = ( currentTime - timerStartTime ) / 10;
+    m = s / 60;
+    s = s % 60;
+    h = m / 60;
+    m = m % 60;
+
+    // rollover once we hit one day
+    if ( h > 24 ) {
+        stopish_set_time_start( stopish_current_time(  ) );
+        h = m = s = ss = 0;
+    }
+
+    timeBuffer = malloc( 64 );
+    sprintf( timeBuffer, "%.02d:%.02d:%.02d.%.1d",
+             h, m, s, ss );
+
+    return timeBuffer;
+}
+
+
+void stopish_set_time_start( long int time )
+{
+    // reset timer to user-inputted time
+    timerStartTime = time;
+    timerSave = 0;
+}
+
+
+void stopish_timer_resume( void )
+{
+    timerStartTime = stopish_current_time(  );
+    timerStartTime -= timerSave;
+}
+
+
+void stopish_timer_save( void )
+{
+    // save time counter
+    timerSave = stopish_current_time(  ) - timerStartTime;
+}
+
+
+long int stopish_current_time( void )
+{
+    struct timeval tv;
+    int s, us;
+
+    gettimeofday( &tv, NULL );
+    s = tv.tv_sec % 100000;
+    us = tv.tv_usec / 100000;
+
+    return ( s * 10 + us );
+}