From 5474e4a2f6f2f455bdaedb7630ba7eef8ed21db1 Mon Sep 17 00:00:00 2001 From: Michael Cronenworth Date: Wed, 9 Dec 2009 22:06:16 -0600 Subject: [PATCH] Implement more functionality: - Start, pause, and resume. - Reset button. - Timer history. --- src/Makefile.am | 2 +- src/stopish.c | 191 +++++++++++++++++++++++++++++++++---------------------- src/stopish.h | 42 ++++++++++++ src/timer.c | 119 ++++++++++++++++++++++++++++++++++ 4 files changed, 278 insertions(+), 76 deletions(-) create mode 100644 src/stopish.h create mode 100644 src/timer.c diff --git a/src/Makefile.am b/src/Makefile.am index 9d7cd3d..a6989ef 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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) diff --git a/src/stopish.c b/src/stopish.c index c1fd229..a201cd4 100644 --- a/src/stopish.c +++ b/src/stopish.c @@ -17,28 +17,29 @@ // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, // MA 02110-1301, USA. - #include #include #include - #include #include +#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 ), "00:00:00.0" ); - gtk_container_add( GTK_CONTAINER( hBox ), timerLabel ); + gtk_label_set_markup( GTK_LABEL( timerLabel ), + "00:00:00.0" ); + 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 ), - "00:00:00.0" ); + // 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 ), + "00:00:00.0" ); + 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, "%.02d:%.02d:%.02d.%.1d", 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 index 0000000..986e3ae --- /dev/null +++ b/src/stopish.h @@ -0,0 +1,42 @@ +// stopish.h +// +// Copyright 2009 Michael Cronenworth +// +// 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 index 0000000..ca1c41d --- /dev/null +++ b/src/timer.c @@ -0,0 +1,119 @@ +// timer.c +// +// Copyright 2009 Michael Cronenworth +// +// 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 +#include +#include +#include +#include + +#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, "%s", 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 ); +} -- 1.7.9.5