// 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[] )
}
-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 );
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 );
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 );
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( );
}
--- /dev/null
+// 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 );
+}