X-Git-Url: http://git.maemo.org/git/?p=stopish;a=blobdiff_plain;f=src%2Fstopish-countdown.c;fp=src%2Fstopish-countdown.c;h=90514b989b911b5a38eabc4a7865079a6477fcc5;hp=0000000000000000000000000000000000000000;hb=f293aee603c7b4abfb88e3bf8ba44cad54cc2e91;hpb=24378226940341b1a14ef3039042f8d643f570ec 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 ) ); +}