From f293aee603c7b4abfb88e3bf8ba44cad54cc2e91 Mon Sep 17 00:00:00 2001 From: Michael Cronenworth Date: Fri, 19 Feb 2010 13:27:30 -0600 Subject: [PATCH] Add countdown functionality with same modes as the stopwatch. Also, add about dialog. --- src/Makefile.am | 3 +- src/stopish-countdown.c | 457 +++++++++++++++++++++++++++++++++++++++++++++++ src/stopish-stopwatch.c | 94 +++++----- src/stopish.c | 130 ++++++++++---- src/stopish.h | 19 ++ src/timer.c | 17 +- 6 files changed, 639 insertions(+), 81 deletions(-) create mode 100644 src/stopish-countdown.c diff --git a/src/Makefile.am b/src/Makefile.am index 3b3cdeb..06845f2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -8,7 +8,8 @@ bin_PROGRAMS = stopish -stopish_SOURCES = stopish.c stopish.h stopish-stopwatch.c timer.c +stopish_SOURCES = stopish.c stopish.h stopish-countdown.c \ + stopish-stopwatch.c timer.c stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(DESKTOP_CFLAGS) \ $(DBUS_CFLAGS) $(MCE_CFLAGS) diff --git a/src/stopish-countdown.c b/src/stopish-countdown.c new file mode 100644 index 0000000..90514b9 --- /dev/null +++ b/src/stopish-countdown.c @@ -0,0 +1,457 @@ +// stopish-countdown.c +// +// Copyright 2010 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 "stopish.h" + +struct timerData { + GtkWidget *vBox; + GtkWidget *label; + GtkWidget *labelHour; + GtkWidget *labelMinute; + GtkWidget *labelSecond; +}; + +static struct timerData timerdata; +static int timerHandle = -1; +static GtkWidget *window = NULL; +static GtkWidget *resetButton; +static int startMinutes = 0; +static int startSeconds = 0; + +//Prototypes +static void main_menu( GtkWindow *window ); +static void close_cb( void ); +static void countdown_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label ); +static void countdown_perf_timer_minute( GtkRadioButton* radio, GtkLabel *label ); +static gint timeout_cb( gpointer data ); +static void start_cb( GtkButton* button, gpointer data ); +static void reset_cb( GtkButton* button, gpointer data ); +static void set_cb( GtkButton* button, gpointer data ); + + +void stopish_countdown_new( void ) +{ + GtkWidget *button, *label; + GtkWidget *vBoxMain, *vBox0, *hBox0; + + window = hildon_stackable_window_new( ); + + gtk_container_set_border_width( GTK_CONTAINER( window ), 20 ); + + gtk_window_set_title( GTK_WINDOW( window ), "Stopish" ); + + // attach signals to main window + g_signal_connect( G_OBJECT( window ), "destroy", + G_CALLBACK( close_cb ), NULL ); + g_signal_connect( G_OBJECT( window ), "focus-in-event", + G_CALLBACK( stopish_focus_in_cb ), NULL ); + g_signal_connect( G_OBJECT( window ), "focus-out-event", + G_CALLBACK( stopish_focus_out_cb ), NULL ); + + // initialize menu + main_menu( GTK_WINDOW( window ) ); + + vBoxMain = gtk_vbox_new( FALSE, 10 ); + + // separator + label = gtk_label_new( NULL ); + gtk_container_add( GTK_CONTAINER( vBoxMain ), label ); + + vBox0 = gtk_vbox_new( FALSE, 5 ); + + // countdown area + timerdata.vBox = gtk_vbox_new( FALSE, 0 ); + gtk_container_add( GTK_CONTAINER( vBox0 ), timerdata.vBox ); + gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_countdown_label_timer_landscape( ); + else + stopish_countdown_label_timer_portrait( ); + + // 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 countdown button + button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Start", NULL ); + resetButton = 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 ), resetButton ); + gtk_container_add( GTK_CONTAINER( hBox0 ), button ); + + // reset button + gtk_widget_set_sensitive( resetButton, FALSE ); + g_signal_connect( G_OBJECT( resetButton ), "clicked", + G_CALLBACK( reset_cb ), button ); + gtk_container_add( GTK_CONTAINER( hBox0 ), resetButton ); + + // set button + button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH, + HILDON_BUTTON_ARRANGEMENT_HORIZONTAL, + "Set", NULL ); + g_signal_connect( G_OBJECT( button ), "clicked", + G_CALLBACK( set_cb ), button ); + gtk_container_add( GTK_CONTAINER( hBox0 ), button ); + + + gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 ); + gtk_container_add( GTK_CONTAINER( window ), vBoxMain ); + + gtk_widget_show_all( window ); +} + + +void stopish_countdown_label_timer_landscape( void ) +{ + gtk_widget_set_size_request( timerdata.vBox, 800, -1 ); + + gtk_widget_destroy( timerdata.label ); + timerdata.label = gtk_label_new( NULL ); + if ( stopish_timer_get_precision( ) == TIMER_PRECISION_MINUTE ) + gtk_label_set_markup( GTK_LABEL( timerdata.label ), + "" + "00:00.0" ); + else + gtk_label_set_markup( GTK_LABEL( timerdata.label ), + "" + "00:00:00.0" ); + gtk_misc_set_alignment( GTK_MISC( timerdata.label ), 0.5f, 0.5f ); + gtk_container_add( GTK_CONTAINER( timerdata.vBox ), timerdata.label ); + gtk_widget_show( timerdata.label ); +} + + +void stopish_countdown_label_timer_portrait( void ) +{ + GtkWidget *vBox, *hBox, *label; + + gtk_widget_set_size_request( timerdata.vBox, 480, -1 ); + + gtk_widget_destroy( timerdata.label ); + vBox = gtk_vbox_new( FALSE, 10 ); + + if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) { + hBox = gtk_hbox_new( FALSE, 10 ); + label = gtk_label_new( "Hours" ); + gtk_widget_set_size_request( label, 100, -1 ); + gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f ); + gtk_container_add( GTK_CONTAINER( hBox ), label ); + timerdata.labelHour = gtk_label_new( NULL ); + gtk_widget_set_size_request( timerdata.labelHour, 350, -1 ); + gtk_misc_set_alignment( GTK_MISC( timerdata.labelHour ), 0.0f, 0.5f ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ), + "" + "00" ); + gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelHour ); + gtk_container_add( GTK_CONTAINER( vBox ), hBox ); + } + + hBox = gtk_hbox_new( FALSE, 10 ); + label = gtk_label_new( "Minutes" ); + gtk_widget_set_size_request( label, 100, -1 ); + gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f ); + gtk_container_add( GTK_CONTAINER( hBox ), label ); + timerdata.labelMinute = gtk_label_new( NULL ); + gtk_widget_set_size_request( timerdata.labelMinute, 350, -1 ); + gtk_misc_set_alignment( GTK_MISC( timerdata.labelMinute ), 0.0f, 0.5f ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ), + "" + "00" ); + gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelMinute ); + gtk_container_add( GTK_CONTAINER( vBox ), hBox ); + + hBox = gtk_hbox_new( FALSE, 10 ); + label = gtk_label_new( "Seconds" ); + gtk_widget_set_size_request( label, 100, -1 ); + gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f ); + gtk_container_add( GTK_CONTAINER( hBox ), label ); + timerdata.labelSecond = gtk_label_new( NULL ); + gtk_widget_set_size_request( timerdata.labelSecond, 350, -1 ); + gtk_misc_set_alignment( GTK_MISC( timerdata.labelSecond ), 0.0f, 0.5f ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ), + "" + "00.0" ); + gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelSecond ); + gtk_container_add( GTK_CONTAINER( vBox ), hBox ); + + timerdata.label = vBox; + gtk_container_add( GTK_CONTAINER( timerdata.vBox ), vBox ); + gtk_widget_show_all( vBox ); +} + + +static void main_menu( GtkWindow *window ) +{ + HildonAppMenu *menu; + GtkWidget *button, *radio; + + menu = ( HildonAppMenu * ) hildon_app_menu_new( ); + + button = gtk_button_new_with_label( "About" ); + g_signal_connect_after( G_OBJECT( button ), "clicked", + G_CALLBACK( stopish_about_cb ), + STOPISH_TYPE_STOPWATCH ); + 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( countdown_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( countdown_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 void close_cb( void ) +{ + gtk_widget_destroy( window ); + if ( timerHandle != -1 && + stopish_get_mode( ) != STOPISH_MODE_RESUME ) + gtk_button_clicked( GTK_BUTTON( resetButton ) ); + startMinutes = startSeconds = 0; + stopish_set_type( STOPISH_TYPE_STOPWATCH ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_stopwatch_label_timer_landscape( ); + else + stopish_stopwatch_label_timer_portrait( ); +} + + +static void countdown_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label ) +{ + stopish_timer_set_precision( TIMER_PRECISION_HOUR ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_countdown_label_timer_landscape( ); + else + stopish_countdown_label_timer_portrait( ); +} + + +static void countdown_perf_timer_minute( GtkRadioButton* radio, GtkLabel *label ) +{ + stopish_timer_set_precision( TIMER_PRECISION_MINUTE ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_countdown_label_timer_landscape( ); + else + stopish_countdown_label_timer_portrait( ); +} + + +// +// Timer callback +// +static gint timeout_cb( gpointer data ) +{ + char formatBuffer[128], tempBuffer[8]; + char *tempString; + + // print to screen + tempString = stopish_get_time_string( ); + if ( tempString == NULL ) { + gtk_button_clicked( GTK_BUTTON( resetButton ) ); + return FALSE; + } + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) { + sprintf( formatBuffer, "" + "%s", tempString ); + gtk_label_set_markup( GTK_LABEL( timerdata.label ), formatBuffer ); + } + else { + if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) { + sprintf( tempBuffer, "%.2s", tempString ); + sprintf( formatBuffer, "" + "%s", tempBuffer ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ), + formatBuffer ); + } + if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) + sprintf( tempBuffer, "%.2s", tempString + 3 ); + else + sprintf( tempBuffer, "%.2s", tempString ); + sprintf( formatBuffer, "" + "%s", tempBuffer ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ), + formatBuffer ); + if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) + sprintf( tempBuffer, "%.4s", tempString + 6 ); + else + sprintf( tempBuffer, "%.4s", tempString + 3 ); + sprintf( formatBuffer, "" + "%s", tempBuffer ); + gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ), + formatBuffer ); + } + free( tempString ); + + return TRUE; +} + + +static void start_cb( GtkButton* button, gpointer data ) +{ + long int offset; + + if ( stopish_get_mode( ) == STOPISH_MODE_START ) { + // set label text and add timer handle + offset = ( startMinutes * 600 ) + ( startSeconds * 10 ); + if ( offset <= 0 ) + return; + gtk_button_set_label( button, "Pause" ); + stopish_set_mode( STOPISH_MODE_PAUSE ); + stopish_set_time_start( stopish_current_time( ) + offset ); + timerHandle = g_timeout_add( 100, timeout_cb, NULL ); + } + else if ( stopish_get_mode( ) == STOPISH_MODE_RESUME ) { + // resume timer + gtk_button_set_label( button, "Pause" ); + stopish_set_mode( STOPISH_MODE_PAUSE ); + stopish_timer_resume( ); + timerHandle = g_timeout_add( 100, timeout_cb, NULL ); + } + else { + // pause timer, remove timeout + gtk_button_set_label( button, "Resume" ); + stopish_set_mode( STOPISH_MODE_RESUME ); + g_source_remove( timerHandle ); + timerHandle = -1; + stopish_timer_save( ); + } + + // allow user to reset timer + gtk_widget_set_sensitive( GTK_WIDGET( data ), TRUE ); +} + + +static void reset_cb( GtkButton* button, gpointer data ) +{ + if ( stopish_get_mode( ) == STOPISH_MODE_RESUME ) + stopish_timer_resume( ); + + // set label text and remove timer handle + gtk_button_set_label( GTK_BUTTON( data ), "Start" ); + stopish_set_mode( STOPISH_MODE_START ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_countdown_label_timer_landscape( ); + else + stopish_countdown_label_timer_portrait( ); + g_source_remove( timerHandle ); + timerHandle = -1; + + // reset start time + stopish_set_time_start( 0 ); + + // disallow user to reset timer + gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE ); +} + + +static void set_cb( GtkButton* button, gpointer data ) +{ + GtkWidget *picker; + GtkWidget *selector; + GtkListStore *minutes, *seconds; + GtkTreeIter iter; + HildonTouchSelectorColumn *column = NULL; + int i, ret; + + // create popup window for setting start time + picker = hildon_picker_dialog_new( GTK_WINDOW( window ) ); + gtk_window_set_title( GTK_WINDOW( picker ), "Set Timer Start" ); + + selector = hildon_touch_selector_new( ); + + minutes = gtk_list_store_new( 1, G_TYPE_INT ); + for ( i = 0; i < 60; ++i ) { + gtk_list_store_append( minutes, &iter ); + gtk_list_store_set( minutes, &iter, 0, i, -1 ); + } + + seconds = gtk_list_store_new( 1, G_TYPE_INT ); + for ( i = 0; i < 60; ++i ) { + gtk_list_store_append( seconds, &iter ); + gtk_list_store_set( seconds, &iter, 0, i, -1 ); + } + + column = hildon_touch_selector_append_text_column( HILDON_TOUCH_SELECTOR( selector ), + GTK_TREE_MODEL( minutes ), + TRUE ); + hildon_touch_selector_column_set_text_column( column, 0 ); + g_object_unref( minutes ); + + column = hildon_touch_selector_append_text_column( HILDON_TOUCH_SELECTOR( selector ), + GTK_TREE_MODEL( seconds ), + TRUE ); + hildon_touch_selector_column_set_text_column( column, 0 ); + g_object_unref( seconds ); + + hildon_picker_dialog_set_selector( HILDON_PICKER_DIALOG( picker ), + HILDON_TOUCH_SELECTOR( selector ) ); + + ret = gtk_dialog_run( GTK_DIALOG( picker ) ); + + // evaluate dialog response + switch ( ret ) { + case GTK_RESPONSE_OK: + startMinutes = + hildon_touch_selector_get_active( HILDON_TOUCH_SELECTOR( selector ), + 0 ); + startSeconds = + hildon_touch_selector_get_active( HILDON_TOUCH_SELECTOR( selector ), + 1 ); + break; + default: + break; + } + gtk_widget_destroy( GTK_WIDGET( picker ) ); +} diff --git a/src/stopish-stopwatch.c b/src/stopish-stopwatch.c index 5129c8d..02f19b7 100644 --- a/src/stopish-stopwatch.c +++ b/src/stopish-stopwatch.c @@ -32,10 +32,8 @@ struct timerData { }; static struct timerData timerdata; -static GtkWidget *timerHistoryLabel1 = NULL; -static GtkWidget *timerHistoryLabel2 = NULL; -static GtkWidget *timerHistoryLabel3 = NULL; -static GtkWidget *timerHistoryLabel4 = NULL; +static GtkWidget *timerHistoryLabel[4]; +static GtkWidget *resetButton; static GSList *historyList = NULL; static int timerHandle = -1; @@ -47,7 +45,7 @@ static void reset_cb( GtkButton* button, gpointer data ); GtkWindow *stopish_stopwatch_new( void ) { - GtkWidget *window, *button, *button0, *label; + GtkWidget *window, *button, *label; GtkWidget *vBoxMain, *vBox0, *hBox0; window = hildon_stackable_window_new( ); @@ -70,20 +68,20 @@ GtkWindow *stopish_stopwatch_new( void ) stopish_stopwatch_label_timer_landscape( ); // history area - timerHistoryLabel1 = gtk_label_new( NULL ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ), + timerHistoryLabel[0] = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[0] ), " " ); - 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 ), + gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel[0], FALSE, FALSE, 0 ); + timerHistoryLabel[1] = gtk_label_new( NULL ); + gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel[1], FALSE, FALSE, 0 ); + timerHistoryLabel[2] = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[2] ), " " ); - gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 ); - timerHistoryLabel4 = gtk_label_new( NULL ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ), + gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel[2], FALSE, FALSE, 0 ); + timerHistoryLabel[3] = gtk_label_new( NULL ); + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[3] ), " " ); - gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel4, FALSE, FALSE, 0 ); + gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel[3], FALSE, FALSE, 0 ); gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 ); @@ -99,18 +97,18 @@ GtkWindow *stopish_stopwatch_new( void ) 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 ); + resetButton = 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 ); + G_CALLBACK( start_cb ), resetButton ); gtk_container_add( GTK_CONTAINER( hBox0 ), button ); // reset button - gtk_widget_set_sensitive( button0, FALSE ); - g_signal_connect( G_OBJECT( button0 ), "clicked", + gtk_widget_set_sensitive( resetButton, FALSE ); + g_signal_connect( G_OBJECT( resetButton ), "clicked", G_CALLBACK( reset_cb ), button ); - gtk_container_add( GTK_CONTAINER( hBox0 ), button0 ); + gtk_container_add( GTK_CONTAINER( hBox0 ), resetButton ); gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 ); @@ -122,6 +120,15 @@ GtkWindow *stopish_stopwatch_new( void ) } +void stopish_stopwatch_reset( void ) +{ + if ( timerHandle == -1 && + stopish_get_mode( ) != STOPISH_MODE_RESUME ) + return; + gtk_button_clicked( GTK_BUTTON( resetButton ) ); +} + + void stopish_stopwatch_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label ) { stopish_timer_set_precision( TIMER_PRECISION_HOUR ); @@ -151,12 +158,12 @@ void stopish_stopwatch_label_timer_landscape( void ) if ( stopish_timer_get_precision( ) == TIMER_PRECISION_MINUTE ) gtk_label_set_markup( GTK_LABEL( timerdata.label ), "" + "size=\"80000\" weight=\"ultrabold\">" "00:00.0" ); else gtk_label_set_markup( GTK_LABEL( timerdata.label ), "" + "size=\"80000\" weight=\"ultrabold\">" "00:00:00.0" ); gtk_misc_set_alignment( GTK_MISC( timerdata.label ), 0.5f, 0.5f ); gtk_container_add( GTK_CONTAINER( timerdata.vBox ), timerdata.label ); @@ -184,7 +191,7 @@ void stopish_stopwatch_label_timer_portrait( void ) gtk_misc_set_alignment( GTK_MISC( timerdata.labelHour ), 0.0f, 0.5f ); gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ), "" + "size=\"90000\" weight=\"ultrabold\">" "00" ); gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelHour ); gtk_container_add( GTK_CONTAINER( vBox ), hBox ); @@ -200,7 +207,7 @@ void stopish_stopwatch_label_timer_portrait( void ) gtk_misc_set_alignment( GTK_MISC( timerdata.labelMinute ), 0.0f, 0.5f ); gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ), "" + "size=\"90000\" weight=\"ultrabold\">" "00" ); gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelMinute ); gtk_container_add( GTK_CONTAINER( vBox ), hBox ); @@ -215,7 +222,7 @@ void stopish_stopwatch_label_timer_portrait( void ) gtk_misc_set_alignment( GTK_MISC( timerdata.labelSecond ), 0.0f, 0.5f ); gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ), "" + "size=\"90000\" weight=\"ultrabold\">" "00.0" ); gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelSecond ); gtk_container_add( GTK_CONTAINER( vBox ), hBox ); @@ -226,7 +233,6 @@ void stopish_stopwatch_label_timer_portrait( void ) } - // // Timer callback // @@ -239,7 +245,7 @@ static gint timeout_cb( gpointer data ) tempString = stopish_get_time_string( ); if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) { sprintf( formatBuffer, "" + "size=\"80000\" weight=\"ultrabold\">" "%s", tempString ); gtk_label_set_markup( GTK_LABEL( timerdata.label ), formatBuffer ); } @@ -247,7 +253,7 @@ static gint timeout_cb( gpointer data ) if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) { sprintf( tempBuffer, "%.2s", tempString ); sprintf( formatBuffer, "" + "size=\"90000\" weight=\"ultrabold\">" "%s", tempBuffer ); gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ), formatBuffer ); @@ -257,7 +263,7 @@ static gint timeout_cb( gpointer data ) else sprintf( tempBuffer, "%.2s", tempString ); sprintf( formatBuffer, "" + "size=\"90000\" weight=\"ultrabold\">" "%s", tempBuffer ); gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ), formatBuffer ); @@ -266,7 +272,7 @@ static gint timeout_cb( gpointer data ) else sprintf( tempBuffer, "%.4s", tempString + 3 ); sprintf( formatBuffer, "" + "size=\"90000\" weight=\"ultrabold\">" "%s", tempBuffer ); gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ), formatBuffer ); @@ -299,6 +305,7 @@ static void start_cb( GtkButton* button, gpointer data ) stopish_set_mode( STOPISH_MODE_RESUME ); g_source_remove( timerHandle ); stopish_timer_save( ); + timerHandle = -1; } // allow user to reset timer @@ -318,43 +325,38 @@ static void reset_cb( GtkButton* button, gpointer data ) // set label text and remove timer handle gtk_button_set_label( GTK_BUTTON( data ), "Start" ); stopish_set_mode( STOPISH_MODE_START ); - if ( stopish_timer_get_precision( ) == TIMER_PRECISION_MINUTE ) - gtk_label_set_markup( GTK_LABEL( timerdata.label ), - "" - "00:00.0" ); + if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) + stopish_stopwatch_label_timer_landscape( ); else - gtk_label_set_markup( GTK_LABEL( timerdata.label ), - "" - "00:00:00.0" ); + stopish_stopwatch_label_timer_portrait( ); g_source_remove( timerHandle ); + timerHandle = -1; // add current time to history historyList = g_slist_prepend( historyList, ( gpointer ) stopish_get_time_string( ) ); sprintf( formatString, "%s", ( char * ) historyList->data ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ), + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[0] ), formatString ); tempList = historyList; tempList = g_slist_next( tempList ); if ( tempList ) { - gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ), + gtk_label_set_text( GTK_LABEL( timerHistoryLabel[1] ), ( char * ) tempList->data ); } tempList = g_slist_next( tempList ); if ( tempList ) { sprintf( formatString, "%s", ( char * ) tempList->data ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ), + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[2] ), formatString ); } tempList = g_slist_next( tempList ); if ( tempList ) { sprintf( formatString, "%s", ( char * ) tempList->data ); - gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ), + gtk_label_set_markup( GTK_LABEL( timerHistoryLabel[3] ), formatString ); } diff --git a/src/stopish.c b/src/stopish.c index b8923ab..af7a7da 100644 --- a/src/stopish.c +++ b/src/stopish.c @@ -35,6 +35,7 @@ typedef struct _AppData AppData; struct _AppData { GtkWindow *main_window; + GtkWindow *countdown_window; osso_context_t *osso_context; DBusConnection *system_bus; }; @@ -43,17 +44,15 @@ struct _AppData { static AppData appdata; static int stopishMode = STOPISH_MODE_START; 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 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, @@ -84,9 +83,9 @@ int main( int argc, char *argv[] ) 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( focus_in_cb ), NULL ); + G_CALLBACK( stopish_focus_in_cb ), NULL ); g_signal_connect( G_OBJECT( appdata.main_window ), "focus-out-event", - G_CALLBACK( focus_out_cb ), NULL ); + G_CALLBACK( stopish_focus_out_cb ), NULL ); // setup main menu main_menu( appdata.main_window ); @@ -131,6 +130,36 @@ gint dbus_callback( const gchar *interface, const gchar *method, } +void stopish_about_cb( GtkButton* button, gpointer data ) +{ + 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] ); +} + + int stopish_get_mode( void ) { return stopishMode; @@ -143,17 +172,60 @@ void stopish_set_mode( int newMode ) } +int stopish_get_type( void ) +{ + return stopishType; +} + + +void stopish_set_type( int newType ) +{ + stopishType = newType; +} + + int stopish_get_orientation( void ) { return stopishOrientation; } +gboolean stopish_focus_in_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ) +{ + // enable accelerometer hardware for portrait mode support + accelerometer_enable( ); + + return FALSE; +} + + +gboolean stopish_focus_out_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ) +{ + // disable accelerometer for battery savings + accelerometer_disable( ); + + return FALSE; +} + + static void main_menu( GtkWindow *window ) { - GtkWidget *menu, *radio; + HildonAppMenu *menu; + GtkWidget *button, *radio; + + menu = ( HildonAppMenu * ) hildon_app_menu_new( ); - menu = 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" ); @@ -170,42 +242,30 @@ static void main_menu( GtkWindow *window ) hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) ); // default to minute - gtk_toggle_button_set_active( radio, TRUE ); + gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radio ), TRUE ); - gtk_widget_show_all( menu ); + gtk_widget_show_all( GTK_WIDGET( menu ) ); hildon_window_set_app_menu( HILDON_WINDOW( window ), menu ); } -static void close_cb( GtkButton* button, 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( ); -} - - -static gboolean focus_in_cb( GtkWidget *widget, GdkEventFocus *event, - gpointer data ) +static void change_type_cb( GtkButton* button, gpointer data ) { - // enable accelerometer hardware for portrait mode support - accelerometer_enable( ); - - return FALSE; + stopish_stopwatch_reset( ); + stopishType = STOPISH_TYPE_COUNTDOWN; + stopish_countdown_new( ); } -static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event, - gpointer data ) +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( ); } @@ -248,13 +308,19 @@ static DBusHandlerResult mce_filter_func( DBusConnection * connection, if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) ) { hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ), HILDON_PORTRAIT_MODE_REQUEST ); - stopish_stopwatch_label_timer_portrait( ); + 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 ); - stopish_stopwatch_label_timer_landscape( ); + if ( stopishType == STOPISH_TYPE_STOPWATCH ) + stopish_stopwatch_label_timer_landscape( ); + else + stopish_countdown_label_timer_landscape( ); stopishOrientation = STOPISH_LANDSCAPE; } } diff --git a/src/stopish.h b/src/stopish.h index 1b87d87..d5d378c 100644 --- a/src/stopish.h +++ b/src/stopish.h @@ -23,10 +23,16 @@ #include +#define STOPISH_VERSION_NUM 0.9.3 +#define STOPISH_VERSION_STR "0.9.3" + #define STOPISH_MODE_START 0 #define STOPISH_MODE_PAUSE 1 #define STOPISH_MODE_RESUME 2 +#define STOPISH_TYPE_STOPWATCH 0 +#define STOPISH_TYPE_COUNTDOWN 1 + #define STOPISH_PORTRAIT 0 #define STOPISH_LANDSCAPE 1 @@ -36,12 +42,25 @@ // stopish.c gint dbus_callback( const gchar *interface, const gchar *method, GArray *arguments, gpointer data, osso_rpc_t *retval ); +void stopish_about_cb( GtkButton* button, gpointer data ); int stopish_get_mode( void ); +int stopish_get_type( void ); int stopish_get_orientation( void ); void stopish_set_mode( int newMode ); +void stopish_set_type( int newType ); +gboolean stopish_focus_in_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ); +gboolean stopish_focus_out_cb( GtkWidget *widget, GdkEventFocus *event, + gpointer data ); + +// stopish-countdown.c +void stopish_countdown_new( void ); +void stopish_countdown_label_timer_landscape( void ); +void stopish_countdown_label_timer_portrait( void ); // stopish-stopwatch.c GtkWindow *stopish_stopwatch_new( void ); +void stopish_stopwatch_reset( void ); void stopish_stopwatch_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label ); void stopish_stopwatch_perf_timer_minute( GtkRadioButton* radio, GtkLabel *label ); void stopish_stopwatch_label_timer_landscape( void ); diff --git a/src/timer.c b/src/timer.c index a17e21f..fe42c75 100644 --- a/src/timer.c +++ b/src/timer.c @@ -60,13 +60,26 @@ char *stopish_get_time_string( void ) h = m = s = ss = 0; } + if ( stopish_get_type( ) == STOPISH_TYPE_COUNTDOWN ) { + h = -h; + m = -m; + s = -s; + ss = -ss; + } + // countdown check + if ( stopish_get_type( ) == STOPISH_TYPE_COUNTDOWN && + ( h == 0 && m == 0 && s == 0 && ss == 0 ) ) + return NULL; + timeBuffer = malloc( 64 ); if ( timerPrecision == TIMER_PRECISION_MINUTE ) sprintf( timeBuffer, "%.02d:%.02d.%.1d", - m, s, ss ); + ( unsigned int ) m, ( unsigned int ) s, + ( unsigned int ) ss ); else sprintf( timeBuffer, "%.02d:%.02d:%.02d.%.1d", - h, m, s, ss ); + ( unsigned int ) h, ( unsigned int ) m, + ( unsigned int ) s, ( unsigned int ) ss ); return timeBuffer; } -- 1.7.9.5