*Hildon-ize the app for better widget support. rel-0-9-1
authorMichael Cronenworth <michael@melchior.(none)>
Wed, 16 Dec 2009 03:17:31 +0000 (21:17 -0600)
committerMichael Cronenworth <michael@melchior.(none)>
Wed, 16 Dec 2009 03:17:31 +0000 (21:17 -0600)
*Add orientation support (Portrait Mode) and restructure the UI
 to better handle it when in portrait.

configure.ac
debian/changelog
debian/control
src/Makefile.am
src/stopish.c
src/timer.c

index 7192714..3f2b8fa 100644 (file)
@@ -28,6 +28,14 @@ PKG_CHECK_MODULES(DESKTOP, libhildondesktop-1)
 AC_SUBST(DESKTOP_LIBS)
 AC_SUBST(DESKTOP_CFLAGS)
 
+PKG_CHECK_MODULES(DBUS, dbus-1)
+AC_SUBST(DBUS_LIBS)
+AC_SUBST(DBUS_CFLAGS)
+
+PKG_CHECK_MODULES(MCE, mce)
+AC_SUBST(MCE_LIBS)
+AC_SUBST(MCE_CFLAGS)
+
 # Application icon install directories
 icon_16x16dir=$datadir/icons/hicolor/16x16/hildon
 icon_26x26dir=$datadir/icons/hicolor/26x26/hildon
index 0724494..409350c 100644 (file)
@@ -1,3 +1,10 @@
+stopish (0.9.1-1) unstable; urgency=low
+
+  * Hildon-ize me.
+  * Add orientation support. A.K.A. Portrait Mode
+
+ -- Michael Cronenworth <mike@cchtml.com>  Tue, 15 Dec 2009 21:03:15 -0600
+
 stopish (0.9.0-3) unstable; urgency=low
 
   * Remove debug package.
index 0ad101a..9fff40c 100644 (file)
@@ -7,11 +7,13 @@ Build-Depends: debhelper (>= 4.0.0), libgtk2.0-dev, libosso-dev (>= 1),
 Standards-Version: 3.7.3
 
 Package: stopish
-Section: user/office
+Section: user/utilities
 Architecture: any
 Depends: ${shlibs:Depends}, hildon-desktop, libgtk2.0-bin
-Description: A stopwatch when you need to keep track of the length of
- an important event.
+Description: A basic stopwatch with portrait mode support.
+ Stopish is the beginning of what will become an advanced stopwatch and
+ countdown timer. With portrait support, you can use this app no matter
+ how you hold your device.
 Xsbc-Bugtracker: https://garage.maemo.org/tracker/?atid=4340&group_id=1158
 Maemo-Icon-26:
  iVBORw0KGgoAAAANSUhEUgAAABoAAAAaCAYAAACpSkzOAAAAAXNSR0IArs4c
index a6989ef..4d70453 100644 (file)
@@ -10,5 +10,7 @@ bin_PROGRAMS = stopish
 
 stopish_SOURCES = stopish.c stopish.h timer.c
 
-stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS)
-stopish_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(DESKTOP_LIBS)
+stopish_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS) $(DESKTOP_CFLAGS) \
+                                $(DBUS_CFLAGS) $(MCE_CFLAGS)
+stopish_LDADD = $(GTK_LIBS) $(OSSO_LIBS) $(DESKTOP_LIBS) $(DBUS_LIBS) \
+                $(MCE_LIBS)
index 9b8b494..e44879d 100644 (file)
 #include <sys/time.h>
 #include <gtk/gtk.h>
 #include <libosso.h>
+#include <hildon/hildon.h>
+#include <dbus/dbus.h>
+#include <mce/mode-names.h>
+#include <mce/dbus-names.h>
+#define MCE_SIGNAL_MATCH "type='signal'," \
+        "interface='" MCE_SIGNAL_IF   "'," \
+        "member='" MCE_DEVICE_ORIENTATION_SIG "'"
 
 #include "stopish.h"
 
+// Application data struct
+typedef struct _AppData AppData;
+struct _AppData {
+    GtkWindow *main_window;
+    osso_context_t *osso_context;
+    DBusConnection *system_bus;
+};
+
+static AppData appdata;
 static GtkWidget *timerLabel = NULL;
 static GtkWidget *timerHistoryLabel1 = NULL;
 static GtkWidget *timerHistoryLabel2 = NULL;
@@ -41,27 +57,50 @@ 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 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,
+                                          DBusMessage * message,
+                                          void *data );
 
 
 int main( int argc, char *argv[] )
 {
-    osso_context_t *ctxt;
     osso_return_t ret;
-    GtkWindow *window;
-
-    //printf( "stopish: starting up\n" );
+    HildonProgram *program;
 
-    ctxt = osso_initialize( "com.nokia.stopish", PACKAGE_VERSION, TRUE, NULL );
-    if ( ctxt == NULL ) {
+    appdata.osso_context = osso_initialize( "com.nokia.stopish",
+                                            PACKAGE_VERSION, TRUE, NULL );
+    if ( appdata.osso_context == NULL ) {
         fprintf( stderr, "osso_initialize failed.\n" );
         exit( 1 );
     }
 
-    gtk_init( &argc, &argv );
-
-    window = stopish_new(  );
+    // initialize Hildonized GTK libraries
+    hildon_gtk_init( &argc, &argv );
+    program = hildon_program_get_instance(  );
+
+    // create main window
+    appdata.main_window = stopish_new(  );
+    hildon_program_add_window( program, HILDON_WINDOW( appdata.main_window ) );
+
+    // Connect to session bus, add a match rule, install filter callback
+    appdata.system_bus = osso_get_sys_dbus_connection( appdata.osso_context );
+    if ( appdata.system_bus ) {
+        dbus_bus_add_match( appdata.system_bus, MCE_SIGNAL_MATCH, NULL );
+        dbus_connection_add_filter( appdata.system_bus,
+                                    mce_filter_func,
+                                    NULL, NULL );
+    }
+    else
+        g_printerr( "ERROR: Cannot connect to system dbus.\n" );
 
-    ret = osso_rpc_set_default_cb_f( ctxt, dbus_callback, window );
+    ret = osso_rpc_set_default_cb_f( appdata.osso_context,
+                                     dbus_callback, appdata.main_window );
     if ( ret != OSSO_OK ) {
         fprintf( stderr, "osso_rpc_set_default_cb_f failed: %d.\n", ret );
         exit( 1 );
@@ -95,74 +134,86 @@ int stopish_get_mode( void )
 
 static GtkWindow *stopish_new( void )
 {
-    GtkWidget *window, *hBox, *label, *button, *button0;
-    GtkWidget *vBox, *vBox0, *vBox1;
+    GtkWidget *window, *button, *button0, *label;
+    GtkWidget *vBoxMain, *vBox0, *hBox0;
 
-    window = gtk_window_new( GTK_WINDOW_TOPLEVEL );
+    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 ), window );
+    g_signal_connect( G_OBJECT( window ), "focus-in-event",
+                      G_CALLBACK( focus_in_cb ), NULL );
+    g_signal_connect( G_OBJECT( window ), "focus-out-event",
+                      G_CALLBACK( focus_out_cb ), NULL );
 
-    vBox = gtk_vbox_new( FALSE, 20 );
-
-    label = gtk_label_new( "Stopish - The Stopwatch" );
-    gtk_box_pack_start( GTK_BOX( vBox ), label, FALSE, FALSE, 0 );
+    vBoxMain = gtk_vbox_new( FALSE, 10 );
 
-    hBox = gtk_hbox_new( FALSE, 10 );
+    // separator
+    label = gtk_label_new( NULL );
+    gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
 
     // 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_widget_set_size_request( timerLabel, -1, 150 );
     gtk_label_set_markup( GTK_LABEL( timerLabel ),
-                          "<span font_family=\"monospace\" size=\"xx-large\">00:00:00.0</span>" );
-    gtk_box_pack_start( GTK_BOX( vBox0 ), timerLabel, FALSE, FALSE, 0 );
+                          "<span font_family=\"monospace\" "
+                          "size=\"70000\" weight=\"ultrabold\">"
+                          "00:00:00.0</span>" );
+    gtk_container_add( GTK_CONTAINER( vBox0 ), timerLabel );
 
     // history area
     timerHistoryLabel1 = gtk_label_new( NULL );
+    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
+                          "<span size=\"large\"> </span>" );
     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 ),
+                          "<span size=\"small\"> </span>" );
     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel3, FALSE, FALSE, 0 );
     timerHistoryLabel4 = gtk_label_new( NULL );
+    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
+                          "<span size=\"x-small\"> </span>" );
     gtk_box_pack_start( GTK_BOX( vBox0 ), timerHistoryLabel4, FALSE, FALSE, 0 );
-    label = gtk_label_new( NULL );
-    gtk_container_add( GTK_CONTAINER( vBox0 ), label );
 
-    gtk_container_add( GTK_CONTAINER( hBox ), vBox0 );
+    gtk_container_add( GTK_CONTAINER( vBoxMain ), vBox0 );
+
+    // separator
+    label = gtk_label_new( NULL );
+    gtk_container_add( GTK_CONTAINER( vBoxMain ), label );
 
     // button area
-    vBox1 = gtk_vbox_new( FALSE, 15 );
-    gtk_widget_set_size_request( vBox1, 200, -1 );
+    hBox0 = gtk_hbox_new( FALSE, 15 );
+    gtk_widget_set_size_request( hBox0, -1, 80 );
 
     // 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 );
+    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 );
     g_signal_connect( G_OBJECT( button ), "clicked",
                       G_CALLBACK( start_cb ), button0 );
-    gtk_box_pack_start( GTK_BOX( vBox1 ), button, FALSE, FALSE, 0 );
+    gtk_container_add( GTK_CONTAINER( hBox0 ), button );
 
     // 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( hBox0 ), button0 );
 
-    gtk_container_add( GTK_CONTAINER( hBox ), vBox1 );
+    gtk_box_pack_start( GTK_BOX( vBoxMain ), hBox0, FALSE, FALSE, 0 );
 
-    gtk_container_add( GTK_CONTAINER( vBox ), hBox );
-
-    gtk_container_add( GTK_CONTAINER( window ), vBox );
+    gtk_container_add( GTK_CONTAINER( window ), vBoxMain );
 
     gtk_widget_show_all( window );
 
@@ -203,7 +254,7 @@ static void reset_cb( GtkButton* button, gpointer data )
 {
     GSList *tempList;
     char *tempString;
-    char formatString[64];
+    char formatString[128];
 
     if ( stopishMode == STOPISH_MODE_RESUME )
         stopish_timer_resume(  );
@@ -212,32 +263,34 @@ static void reset_cb( GtkButton* button, gpointer data )
     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>" );
+                          "<span font_family=\"monospace\" "
+                          "size=\"70000\" weight=\"ultrabold\">"
+                          "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 );
+    sprintf( formatString, "<span size=\"large\">%s</span>",
+             ( char * ) historyList->data );
+    gtk_label_set_markup( GTK_LABEL( timerHistoryLabel1 ),
+                          formatString );
     tempList = historyList;
     tempList = g_slist_next( tempList );
     if ( tempList ) {
-        sprintf( formatString, "<span size=\"small\">%s</span>",
-                 ( char * ) tempList->data );
-        gtk_label_set_markup( GTK_LABEL( timerHistoryLabel2 ),
-                              formatString );
+        gtk_label_set_text( GTK_LABEL( timerHistoryLabel2 ),
+                            ( char * ) tempList->data );
     }
     tempList = g_slist_next( tempList );
     if ( tempList ) {
-        sprintf( formatString, "<span size=\"x-small\">%s</span>",
+        sprintf( formatString, "<span size=\"small\">%s</span>",
                  ( char * ) tempList->data );
         gtk_label_set_markup( GTK_LABEL( timerHistoryLabel3 ),
                               formatString );
     }
     tempList = g_slist_next( tempList );
     if ( tempList ) {
-        sprintf( formatString, "<span size=\"xx-small\">%s</span>",
+        sprintf( formatString, "<span size=\"x-small\">%s</span>",
                  ( char * ) tempList->data );
         gtk_label_set_markup( GTK_LABEL( timerHistoryLabel4 ),
                               formatString );
@@ -261,7 +314,81 @@ static void reset_cb( GtkButton* button, gpointer data )
 
 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 )
+{
+    // enable accelerometer hardware for portrait mode support
+    accelerometer_enable(  );
+
+    return FALSE;
+}
+
+
+static gboolean focus_out_cb( GtkWidget *widget, GdkEventFocus *event,
+                              gpointer data )
+{
+    // disable accelerometer for battery savings
+    accelerometer_disable(  );
+
+    return FALSE;
+}
+
+
+static void accelerometer_enable( void )
+{
+    if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE,
+                              MCE_REQUEST_PATH, MCE_REQUEST_IF,
+                              "req_accelerometer_enable", NULL,
+                              DBUS_TYPE_INVALID ) != OSSO_OK ) {
+        g_printerr("WARN: Cannot enable accelerometers\n");
+    }
+}
+
+
+static void accelerometer_disable( void )
+{
+    if ( osso_rpc_run_system( appdata.osso_context, MCE_SERVICE,
+                              MCE_REQUEST_PATH, MCE_REQUEST_IF,
+                              "req_accelerometer_disable", NULL,
+                              DBUS_TYPE_INVALID ) != OSSO_OK ) {
+        g_printerr("WARN: Cannot disable accelerometers\n");
+    }
+}
+
+
+static DBusHandlerResult mce_filter_func( DBusConnection * connection,
+                                          DBusMessage * message,
+                                          void *data )
+{
+    DBusMessageIter iter;
+    char *rotation = NULL;
+
+    if ( dbus_message_is_signal( message, MCE_SIGNAL_IF,
+                                 MCE_DEVICE_ORIENTATION_SIG ) ) {
+        // here if we received an orientation dbus signal
+        if ( dbus_message_iter_init( message, &iter ) ) {
+            dbus_message_iter_get_basic( &iter, &rotation );
+
+            // Rotate main window
+            if ( !strcmp( rotation, MCE_ORIENTATION_PORTRAIT ) )
+                hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
+                                                      HILDON_PORTRAIT_MODE_REQUEST );
+            else
+                hildon_gtk_window_set_portrait_flags( GTK_WINDOW( appdata.main_window ),
+                                                      ~HILDON_PORTRAIT_MODE_REQUEST );
+        }
+        else
+            g_printerr( "ERROR: dbus_message_iter_init() failed.\n" );
+    }
+
+    return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
+}
index ca1c41d..41f9f3a 100644 (file)
@@ -35,7 +35,7 @@ static long int timerSave = 0;
 gint stopish_timeout_cb( gpointer data )
 {
     GtkLabel *timerLabel;
-    char formatBuffer[64];
+    char formatBuffer[128];
     char *tempString;
 
     if ( !data )
@@ -45,7 +45,9 @@ gint stopish_timeout_cb( gpointer data )
 
     // print to screen
     tempString = stopish_get_time_string(  );
-    sprintf( formatBuffer, "<span font_family=\"monospace\" size=\"xx-large\">%s</span>", tempString );
+    sprintf( formatBuffer, "<span font_family=\"monospace\" "
+                          "size=\"70000\" weight=\"ultrabold\">"
+                          "%s</span>", tempString );
     free( tempString );
     gtk_label_set_markup( GTK_LABEL( timerLabel ), formatBuffer );