3 // Copyright 2010 Michael Cronenworth <mike@cchtml.com>
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18 // MA 02110-1301, USA.
21 #include <hildon/hildon.h>
30 GtkWidget *labelMinute;
31 GtkWidget *labelSecond;
34 static struct timerData timerdata;
35 static int timerHandle = -1;
36 static GtkWidget *window = NULL;
37 static GtkWidget *resetButton;
38 static int startMinutes = 0;
39 static int startSeconds = 0;
42 static void main_menu( GtkWindow *window );
43 static void close_cb( void );
44 static void countdown_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label );
45 static void countdown_perf_timer_minute( GtkRadioButton* radio, GtkLabel *label );
46 static gint timeout_cb( gpointer data );
47 static void start_cb( GtkButton* button, gpointer data );
48 static void reset_cb( GtkButton* button, gpointer data );
49 static void set_cb( GtkButton* button, gpointer data );
52 void stopish_countdown_new( void )
54 GtkWidget *button, *label;
55 GtkWidget *vBoxMain, *vBox0, *hBox0;
57 window = hildon_stackable_window_new( );
59 gtk_container_set_border_width( GTK_CONTAINER( window ), 20 );
61 gtk_window_set_title( GTK_WINDOW( window ), "Stopish" );
63 // attach signals to main window
64 g_signal_connect( G_OBJECT( window ), "destroy",
65 G_CALLBACK( close_cb ), NULL );
66 g_signal_connect( G_OBJECT( window ), "focus-in-event",
67 G_CALLBACK( stopish_focus_in_cb ), NULL );
68 g_signal_connect( G_OBJECT( window ), "focus-out-event",
69 G_CALLBACK( stopish_focus_out_cb ), NULL );
72 main_menu( GTK_WINDOW( window ) );
74 vBoxMain = gtk_vbox_new( FALSE, 10 );
77 label = gtk_label_new( NULL );
78 gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
80 vBox0 = gtk_vbox_new( FALSE, 5 );
83 timerdata.vBox = gtk_vbox_new( FALSE, 0 );
84 gtk_container_add( GTK_CONTAINER( vBox0 ), timerdata.vBox );
85 gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 );
86 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE )
87 stopish_countdown_label_timer_landscape( );
89 stopish_countdown_label_timer_portrait( );
92 label = gtk_label_new( NULL );
93 gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
96 hBox0 = gtk_hbox_new( FALSE, 15 );
97 gtk_widget_set_size_request( hBox0, -1, 80 );
99 // start/pause countdown button
100 button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
101 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
103 resetButton = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
104 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
106 g_signal_connect( G_OBJECT( button ), "clicked",
107 G_CALLBACK( start_cb ), resetButton );
108 gtk_container_add( GTK_CONTAINER( hBox0 ), button );
111 gtk_widget_set_sensitive( resetButton, FALSE );
112 g_signal_connect( G_OBJECT( resetButton ), "clicked",
113 G_CALLBACK( reset_cb ), button );
114 gtk_container_add( GTK_CONTAINER( hBox0 ), resetButton );
117 button = hildon_button_new_with_text( HILDON_SIZE_HALFSCREEN_WIDTH,
118 HILDON_BUTTON_ARRANGEMENT_HORIZONTAL,
120 g_signal_connect( G_OBJECT( button ), "clicked",
121 G_CALLBACK( set_cb ), button );
122 gtk_container_add( GTK_CONTAINER( hBox0 ), button );
125 gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 );
126 gtk_container_add( GTK_CONTAINER( window ), vBoxMain );
128 gtk_widget_show_all( window );
132 void stopish_countdown_label_timer_landscape( void )
134 gtk_widget_set_size_request( timerdata.vBox, 800, -1 );
136 gtk_widget_destroy( timerdata.label );
137 timerdata.label = gtk_label_new( NULL );
138 if ( stopish_timer_get_precision( ) == TIMER_PRECISION_MINUTE )
139 gtk_label_set_markup( GTK_LABEL( timerdata.label ),
140 "<span font_family=\"monospace\" "
141 "size=\"80000\" weight=\"ultrabold\">"
144 gtk_label_set_markup( GTK_LABEL( timerdata.label ),
145 "<span font_family=\"monospace\" "
146 "size=\"80000\" weight=\"ultrabold\">"
147 "00:00:00.0</span>" );
148 gtk_misc_set_alignment( GTK_MISC( timerdata.label ), 0.5f, 0.5f );
149 gtk_container_add( GTK_CONTAINER( timerdata.vBox ), timerdata.label );
150 gtk_widget_show( timerdata.label );
154 void stopish_countdown_label_timer_portrait( void )
156 GtkWidget *vBox, *hBox, *label;
158 gtk_widget_set_size_request( timerdata.vBox, 480, -1 );
160 gtk_widget_destroy( timerdata.label );
161 vBox = gtk_vbox_new( FALSE, 10 );
163 if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) {
164 hBox = gtk_hbox_new( FALSE, 10 );
165 label = gtk_label_new( "Hours" );
166 gtk_widget_set_size_request( label, 100, -1 );
167 gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
168 gtk_container_add( GTK_CONTAINER( hBox ), label );
169 timerdata.labelHour = gtk_label_new( NULL );
170 gtk_widget_set_size_request( timerdata.labelHour, 350, -1 );
171 gtk_misc_set_alignment( GTK_MISC( timerdata.labelHour ), 0.0f, 0.5f );
172 gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ),
173 "<span font_family=\"monospace\" "
174 "size=\"90000\" weight=\"ultrabold\">"
176 gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelHour );
177 gtk_container_add( GTK_CONTAINER( vBox ), hBox );
180 hBox = gtk_hbox_new( FALSE, 10 );
181 label = gtk_label_new( "Minutes" );
182 gtk_widget_set_size_request( label, 100, -1 );
183 gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
184 gtk_container_add( GTK_CONTAINER( hBox ), label );
185 timerdata.labelMinute = gtk_label_new( NULL );
186 gtk_widget_set_size_request( timerdata.labelMinute, 350, -1 );
187 gtk_misc_set_alignment( GTK_MISC( timerdata.labelMinute ), 0.0f, 0.5f );
188 gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ),
189 "<span font_family=\"monospace\" "
190 "size=\"90000\" weight=\"ultrabold\">"
192 gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelMinute );
193 gtk_container_add( GTK_CONTAINER( vBox ), hBox );
195 hBox = gtk_hbox_new( FALSE, 10 );
196 label = gtk_label_new( "Seconds" );
197 gtk_widget_set_size_request( label, 100, -1 );
198 gtk_misc_set_alignment( GTK_MISC( label ), 1.0f, 0.5f );
199 gtk_container_add( GTK_CONTAINER( hBox ), label );
200 timerdata.labelSecond = gtk_label_new( NULL );
201 gtk_widget_set_size_request( timerdata.labelSecond, 350, -1 );
202 gtk_misc_set_alignment( GTK_MISC( timerdata.labelSecond ), 0.0f, 0.5f );
203 gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ),
204 "<span font_family=\"monospace\" "
205 "size=\"90000\" weight=\"ultrabold\">"
207 gtk_container_add( GTK_CONTAINER( hBox ), timerdata.labelSecond );
208 gtk_container_add( GTK_CONTAINER( vBox ), hBox );
210 timerdata.label = vBox;
211 gtk_container_add( GTK_CONTAINER( timerdata.vBox ), vBox );
212 gtk_widget_show_all( vBox );
216 static void main_menu( GtkWindow *window )
219 GtkWidget *button, *radio;
221 menu = ( HildonAppMenu * ) hildon_app_menu_new( );
223 button = gtk_button_new_with_label( "About" );
224 g_signal_connect_after( G_OBJECT( button ), "clicked",
225 G_CALLBACK( stopish_about_cb ),
226 STOPISH_TYPE_STOPWATCH );
227 hildon_app_menu_append( menu, GTK_BUTTON( button ) );
230 radio = gtk_radio_button_new_with_label( NULL, "Hour" );
231 gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON( radio ), FALSE );
232 g_signal_connect_after( G_OBJECT( radio ), "clicked",
233 G_CALLBACK( countdown_perf_timer_hour ), NULL );
234 hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
237 radio = gtk_radio_button_new_with_label_from_widget( GTK_RADIO_BUTTON( radio ), "Minute" );
238 gtk_toggle_button_set_mode( GTK_TOGGLE_BUTTON ( radio ), FALSE );
239 g_signal_connect_after( G_OBJECT( radio ), "clicked",
240 G_CALLBACK( countdown_perf_timer_minute ), NULL );
241 hildon_app_menu_add_filter( menu, GTK_BUTTON( radio ) );
244 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( radio ), TRUE );
246 gtk_widget_show_all( GTK_WIDGET( menu ) );
248 hildon_window_set_app_menu( HILDON_WINDOW( window ), menu );
252 static void close_cb( void )
254 gtk_widget_destroy( window );
255 if ( timerHandle != -1 &&
256 stopish_get_mode( ) != STOPISH_MODE_RESUME )
257 gtk_button_clicked( GTK_BUTTON( resetButton ) );
258 startMinutes = startSeconds = 0;
259 stopish_set_type( STOPISH_TYPE_STOPWATCH );
260 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE )
261 stopish_stopwatch_label_timer_landscape( );
263 stopish_stopwatch_label_timer_portrait( );
267 static void countdown_perf_timer_hour( GtkRadioButton* radio, GtkLabel *label )
269 stopish_timer_set_precision( TIMER_PRECISION_HOUR );
270 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE )
271 stopish_countdown_label_timer_landscape( );
273 stopish_countdown_label_timer_portrait( );
277 static void countdown_perf_timer_minute( GtkRadioButton* radio, GtkLabel *label )
279 stopish_timer_set_precision( TIMER_PRECISION_MINUTE );
280 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE )
281 stopish_countdown_label_timer_landscape( );
283 stopish_countdown_label_timer_portrait( );
290 static gint timeout_cb( gpointer data )
292 char formatBuffer[128], tempBuffer[8];
296 tempString = stopish_get_time_string( );
297 if ( tempString == NULL ) {
298 gtk_button_clicked( GTK_BUTTON( resetButton ) );
301 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE ) {
302 sprintf( formatBuffer, "<span font_family=\"monospace\" "
303 "size=\"80000\" weight=\"ultrabold\">"
304 "%s</span>", tempString );
305 gtk_label_set_markup( GTK_LABEL( timerdata.label ), formatBuffer );
308 if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR ) {
309 sprintf( tempBuffer, "%.2s", tempString );
310 sprintf( formatBuffer, "<span font_family=\"monospace\" "
311 "size=\"90000\" weight=\"ultrabold\">"
312 "%s</span>", tempBuffer );
313 gtk_label_set_markup( GTK_LABEL( timerdata.labelHour ),
316 if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR )
317 sprintf( tempBuffer, "%.2s", tempString + 3 );
319 sprintf( tempBuffer, "%.2s", tempString );
320 sprintf( formatBuffer, "<span font_family=\"monospace\" "
321 "size=\"90000\" weight=\"ultrabold\">"
322 "%s</span>", tempBuffer );
323 gtk_label_set_markup( GTK_LABEL( timerdata.labelMinute ),
325 if ( stopish_timer_get_precision( ) == TIMER_PRECISION_HOUR )
326 sprintf( tempBuffer, "%.4s", tempString + 6 );
328 sprintf( tempBuffer, "%.4s", tempString + 3 );
329 sprintf( formatBuffer, "<span font_family=\"monospace\" "
330 "size=\"90000\" weight=\"ultrabold\">"
331 "%s</span>", tempBuffer );
332 gtk_label_set_markup( GTK_LABEL( timerdata.labelSecond ),
341 static void start_cb( GtkButton* button, gpointer data )
345 if ( stopish_get_mode( ) == STOPISH_MODE_START ) {
346 // set label text and add timer handle
347 offset = ( startMinutes * 600 ) + ( startSeconds * 10 );
350 gtk_button_set_label( button, "Pause" );
351 stopish_set_mode( STOPISH_MODE_PAUSE );
352 stopish_set_time_start( stopish_current_time( ) + offset );
353 timerHandle = g_timeout_add( 100, timeout_cb, NULL );
355 else if ( stopish_get_mode( ) == STOPISH_MODE_RESUME ) {
357 gtk_button_set_label( button, "Pause" );
358 stopish_set_mode( STOPISH_MODE_PAUSE );
359 stopish_timer_resume( );
360 timerHandle = g_timeout_add( 100, timeout_cb, NULL );
363 // pause timer, remove timeout
364 gtk_button_set_label( button, "Resume" );
365 stopish_set_mode( STOPISH_MODE_RESUME );
366 g_source_remove( timerHandle );
368 stopish_timer_save( );
371 // allow user to reset timer
372 gtk_widget_set_sensitive( GTK_WIDGET( data ), TRUE );
376 static void reset_cb( GtkButton* button, gpointer data )
378 if ( stopish_get_mode( ) == STOPISH_MODE_RESUME )
379 stopish_timer_resume( );
381 // set label text and remove timer handle
382 gtk_button_set_label( GTK_BUTTON( data ), "Start" );
383 stopish_set_mode( STOPISH_MODE_START );
384 if ( stopish_get_orientation( ) == STOPISH_LANDSCAPE )
385 stopish_countdown_label_timer_landscape( );
387 stopish_countdown_label_timer_portrait( );
388 g_source_remove( timerHandle );
392 stopish_set_time_start( 0 );
394 // disallow user to reset timer
395 gtk_widget_set_sensitive( GTK_WIDGET( button ), FALSE );
399 static void set_cb( GtkButton* button, gpointer data )
403 GtkListStore *minutes, *seconds;
405 HildonTouchSelectorColumn *column = NULL;
408 // create popup window for setting start time
409 picker = hildon_picker_dialog_new( GTK_WINDOW( window ) );
410 gtk_window_set_title( GTK_WINDOW( picker ), "Set Timer Start" );
412 selector = hildon_touch_selector_new( );
414 minutes = gtk_list_store_new( 1, G_TYPE_INT );
415 for ( i = 0; i < 60; ++i ) {
416 gtk_list_store_append( minutes, &iter );
417 gtk_list_store_set( minutes, &iter, 0, i, -1 );
420 seconds = gtk_list_store_new( 1, G_TYPE_INT );
421 for ( i = 0; i < 60; ++i ) {
422 gtk_list_store_append( seconds, &iter );
423 gtk_list_store_set( seconds, &iter, 0, i, -1 );
426 column = hildon_touch_selector_append_text_column( HILDON_TOUCH_SELECTOR( selector ),
427 GTK_TREE_MODEL( minutes ),
429 hildon_touch_selector_column_set_text_column( column, 0 );
430 g_object_unref( minutes );
432 column = hildon_touch_selector_append_text_column( HILDON_TOUCH_SELECTOR( selector ),
433 GTK_TREE_MODEL( seconds ),
435 hildon_touch_selector_column_set_text_column( column, 0 );
436 g_object_unref( seconds );
438 hildon_picker_dialog_set_selector( HILDON_PICKER_DIALOG( picker ),
439 HILDON_TOUCH_SELECTOR( selector ) );
441 ret = gtk_dialog_run( GTK_DIALOG( picker ) );
443 // evaluate dialog response
445 case GTK_RESPONSE_OK:
447 hildon_touch_selector_get_active( HILDON_TOUCH_SELECTOR( selector ),
450 hildon_touch_selector_get_active( HILDON_TOUCH_SELECTOR( selector ),
456 gtk_widget_destroy( GTK_WIDGET( picker ) );