flipbar.c

Go to the documentation of this file.
00001 /*
00002  * File Name: flipbar.c
00003  */
00004 
00005 /*
00006  * This file is part of settings.
00007  *
00008  * settings is free software: you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation, either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * settings is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00016  * GNU General Public License for more details.
00017  *
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program. If not, see <http://www.gnu.org/licenses/>.
00020  */
00021 
00022 /**
00023  * Copyright (C) 2008 iRex Technologies B.V.
00024  * All rights reserved.
00025  */
00026 
00027 //----------------------------------------------------------------------------
00028 // Include Files
00029 //----------------------------------------------------------------------------
00030 
00031 // system include files, between < >
00032 #include <string.h>
00033 #include <stdlib.h>
00034 #include <unistd.h>
00035 #include <stdio.h>
00036 
00037 #include <gtk/gtk.h>
00038 #include <gdk/gdk.h>
00039 #include <glib.h>
00040 
00041 #include <libergtk/ergtk.h>
00042 
00043 #include "i18n.h"
00044 #include "log.h"
00045 #include "ipc.h"
00046 #include "settings.h"
00047 #include "settings_utils.h"
00048 #include "settings_style.h"
00049 #include "flipbar.h"
00050 
00051 
00052 //----------------------------------------------------------------------------
00053 // Type Declarations
00054 //----------------------------------------------------------------------------
00055 
00056 typedef struct
00057 {
00058     /* 
00059      * Has only effect in portrait orientation
00060      *
00061      * Normal mode: pageturn_inverted = FALSE, Book mode: pageturn_inverted = TRUE
00062      *
00063      * normal mode :: flipbar to right maps to arrow down key  -> next page
00064      *                flipbar to left  maps to arrow up   key  -> prev page 
00065      *
00066      * book   mode :: flipbar to right maps to arrow up   key  -> prev page
00067      *                flipbar to left  maps to arrow down key  -> next page
00068      *
00069      */
00070   
00071     gboolean pageturn_inverted;
00072 } FlipBarSettings;
00073 
00074 
00075 //----------------------------------------------------------------------------
00076 // Global Constants
00077 //----------------------------------------------------------------------------
00078 
00079 #define NUM_FLIPBAR_MODES  2
00080 
00081 
00082 //----------------------------------------------------------------------------
00083 // Static Variables
00084 //----------------------------------------------------------------------------
00085 
00086 static FlipBarSettings g_orig_flipbar_settings;
00087 static FlipBarSettings g_cur_flipbar_settings;
00088 
00089 static GtkWidget* g_flipbar_radios[NUM_FLIPBAR_MODES];  
00090 
00091 
00092 //============================================================================
00093 // Local Function Definitions
00094 //============================================================================
00095 
00096 static GtkWidget* create_flipbar_widgets         (GtkBox* parent);
00097 
00098 static void on_flipbar_changed                   (GtkWidget *widget, gpointer data);
00099 static void init_widgets_with_settings          (void);
00100 static void on_listview_row_activated ( GtkTreeView       *view,
00101                                         GtkTreePath       *path,
00102                                         GtkTreeViewColumn *column,
00103                                         gpointer          user_data );
00104 
00105 
00106 static void on_listview_navigate_cursor ( erGtkListView         *er_listview,
00107         erGtkListViewKeyPress keycode,
00108         gpointer              user_data );
00109 
00110 static gboolean on_focus_in(GtkWidget* widget, gpointer data );
00111 static gboolean on_focus_out(GtkWidget* widget, gpointer data );
00112 
00113 
00114 //============================================================================
00115 // Functions Implementation
00116 //============================================================================
00117 
00118 GtkWidget* create_flipbar_window(GtkWidget* parent)
00119 {
00120     // create top window
00121     GtkWidget* top_window = parent;
00122     gtk_window_maximize(GTK_WINDOW(top_window));
00123     gtk_window_set_resizable(GTK_WINDOW(top_window), FALSE);
00124     gtk_container_set_border_width(GTK_CONTAINER(top_window),WINDOW_BORDER_PADDING  );
00125     gtk_window_set_modal(GTK_WINDOW(top_window), TRUE);
00126 
00127     // top level vbox (vboxtop)
00128     GtkWidget* vboxtop = gtk_vbox_new(FALSE, 3);
00129     gtk_container_add(GTK_CONTAINER(top_window), vboxtop);
00130 
00131     // add header container the title and subtitle of this settings page
00132     create_title(GTK_VBOX(vboxtop), _("Settings"), _("Flipbar Setup"));
00133     
00134     // add the back/exit bar below the title 
00135     GtkWidget* view = create_settingsview();
00136     gtk_box_pack_start(GTK_BOX(vboxtop), view, FALSE, FALSE,0 ); 
00137     g_signal_connect(view, "row-activated", G_CALLBACK(on_listview_row_activated), NULL ) ;
00138     g_signal_connect(view, "navigate-cursor", G_CALLBACK(on_listview_navigate_cursor), NULL ) ;
00139     g_signal_connect(view, "focus-in-event", G_CALLBACK(on_focus_in), NULL );
00140     g_signal_connect(view, "focus-out-event", G_CALLBACK(on_focus_out), NULL );
00141 
00142     // add an alignment below the exit bar
00143     GtkWidget* alignment = gtk_alignment_new(0, 0, 1.0, 0.0);
00144     gtk_container_add(GTK_CONTAINER(vboxtop), alignment);
00145 
00146     // introdude a frame in the alignment
00147     GtkWidget* frame = gtk_frame_new(NULL);
00148     gtk_widget_set_name(frame, "irex-margins-frame");
00149     gtk_container_add(GTK_CONTAINER(alignment), frame);
00150     gtk_container_set_border_width(GTK_CONTAINER(frame), 3);
00151 
00152     // alignment in frame 
00153     GtkWidget* alignment2 = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
00154     gtk_container_add(GTK_CONTAINER(frame), alignment2);
00155     gtk_alignment_set_padding(GTK_ALIGNMENT(alignment2),
00156                               WINDOW_TOP_ALT_PADDING,
00157                               WINDOW_BOTTOM_PADDING,
00158                               WINDOW_H_PADDING,
00159                               WINDOW_H_PADDING);
00160    
00161     // vbox in alignment2
00162     GtkWidget* innervbox = gtk_vbox_new(FALSE, SMALL_SPACING);
00163     gtk_container_add(GTK_CONTAINER(alignment2), innervbox);
00164     
00165     // The margin settings section.
00166     create_flipbar_widgets(GTK_BOX(innervbox));
00167 
00168     // Update widget with current settings.
00169     init_widgets_with_settings();
00170 
00171     gtk_widget_grab_focus(view);
00172 
00173     gtk_widget_show_all(top_window);
00174     return top_window;
00175 }
00176 
00177 
00178 
00179 //============================================================================
00180 // Local Functions Implementation
00181 //============================================================================
00182 
00183 static void on_listview_row_activated ( GtkTreeView       *view,
00184                                         GtkTreePath       *path,
00185                                         GtkTreeViewColumn *column,
00186                                         gpointer          user_data )
00187 {
00188     
00189     save_flipbar_settings();
00190 
00191     main_quit();
00192     return;
00193 }
00194 
00195 static void on_listview_navigate_cursor ( erGtkListView         *er_listview,
00196         erGtkListViewKeyPress keycode,
00197         gpointer              user_data )
00198 {
00199    GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) er_listview);
00200    g_assert( my_selection != NULL ) ;
00201 
00202     // determine new cursor position
00203     switch (keycode)
00204     {
00205         case ERGTK_LIST_VIEW_PRESS_SHORT_DOWN:
00206         case ERGTK_LIST_VIEW_PRESS_LONG_DOWN:
00207             gtk_widget_grab_focus(GTK_WIDGET(g_flipbar_radios[0]));
00208             gtk_tree_selection_unselect_all(my_selection);
00209             break;
00210         default:
00211             LOGPRINTF("illegal erGtkListViewKeyPress [%d]", keycode);
00212             ;  // ignore
00213             break;
00214     }
00215 
00216 }
00217 
00218 static gboolean on_focus_in(GtkWidget* widget, gpointer data )
00219 {
00220     g_assert(widget != NULL ) ;
00221     ergtk_list_view_set_cursor( ERGTK_LIST_VIEW(widget), 0); // row = 0;
00222     return FALSE;
00223 }
00224 
00225 static gboolean on_focus_out(GtkWidget* widget, gpointer data )
00226 {
00227     g_assert(widget != NULL ) ;
00228     GtkTreeSelection* my_selection = gtk_tree_view_get_selection((GtkTreeView*) widget);
00229     g_assert( my_selection != NULL ) ;
00230     gtk_tree_selection_unselect_all(my_selection);
00231     return FALSE;
00232 }
00233 
00234 //============================================================================
00235 // Functions Implementation
00236 //============================================================================
00237 
00238 
00239 void load_flipbar_settings()
00240 {
00241     g_orig_flipbar_settings.pageturn_inverted = get_value_bool(GCONF_PAGETURN_INVERTED);
00242     g_cur_flipbar_settings = g_orig_flipbar_settings;
00243 }
00244 
00245 
00246 void save_flipbar_settings()
00247 {
00248     if (g_cur_flipbar_settings.pageturn_inverted != g_orig_flipbar_settings.pageturn_inverted )
00249     {
00250         set_value_bool(GCONF_PAGETURN_INVERTED, g_cur_flipbar_settings.pageturn_inverted);
00251     }
00252     LOGPRINTF("Saving flipbar settings, done.");
00253 }
00254 
00255 
00256 //============================================================================
00257 // Local Functions Implementation
00258 //============================================================================
00259 
00260 
00261 static GtkWidget* create_radio_button_item(GtkWidget* group, gchar* title, gchar* subtitle)
00262 {
00263     GtkWidget* radio_button = NULL ;
00264     if ( group == NULL ) 
00265     {
00266         radio_button = gtk_radio_button_new(NULL); 
00267     }
00268     else {
00269         radio_button = gtk_radio_button_new_from_widget(GTK_RADIO_BUTTON(group)); 
00270 
00271     }
00272     gtk_widget_set_name(radio_button, "irex-settings-checkbutton");
00273 
00274     // alignment in radio button for some padding
00275     GtkWidget* align = gtk_alignment_new(0, 0.0, 1.0, 1.0);
00276     gtk_container_add(GTK_CONTAINER(radio_button), align);
00277     gtk_alignment_set_padding(GTK_ALIGNMENT(align)
00278                                 , 6 // top
00279                                 , 6 // bottom
00280                                 , 6 // left
00281                                 , 6 // right
00282             );
00283  
00284     // vbox in radio button
00285     GtkWidget* radiovbox = gtk_vbox_new( FALSE, 0);
00286     gtk_container_add(GTK_CONTAINER(align), radiovbox);
00287 
00288     // top level label for radio button ( no margins )
00289     GtkWidget* label = gtk_label_new( title );
00290     gtk_widget_set_name(label, "irex-radio-title");
00291     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
00292     gtk_box_pack_start(GTK_BOX(radiovbox), label, FALSE, FALSE, 0);
00293 
00294     // second level label for radio button ( descriptive test )
00295     label = gtk_label_new( subtitle  );
00296     gtk_widget_set_name(label, "irex-radio-subtitle");
00297     gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.0);
00298     gtk_label_set_line_wrap(GTK_LABEL(label), TRUE);
00299     gtk_widget_set_size_request(label, SETTINGS_LABEL_MAX_WIDTH - 40 , -1);
00300     gtk_box_pack_start(GTK_BOX(radiovbox), label, FALSE, FALSE, 0);
00301 
00302     return radio_button;
00303 }
00304 
00305 
00306 
00307 // Widget Hierarchy
00308 // |--Top Level vbox
00309 //    |--label ("UDS settings")
00310 //    |--label ("Choose the page margin")
00311 //    |--vbox
00312 //       |--radio
00313 //       |--radio
00314 //       |--radio
00315 //       |--radio
00316 static GtkWidget* create_flipbar_widgets(GtkBox* parent)
00317 {
00318 
00319     // Top level vbox.
00320     GtkWidget* top_level_vbox = gtk_vbox_new(FALSE, ITEM_SPACING);
00321     gtk_box_pack_start(parent, top_level_vbox, FALSE, FALSE, 0);
00322 
00323     // The vbox containing radio buttons.
00324     GtkWidget* vbox = gtk_vbox_new(TRUE, 10);
00325     gtk_box_pack_start(GTK_BOX(top_level_vbox), vbox, FALSE, FALSE, 0);
00326 
00327     int i = 0 ;
00328     for (i=0; i<NUM_FLIPBAR_MODES; i++)
00329     {
00330         switch (i)
00331         {
00332             case 0:
00333             {
00334                 // the radio button "Normal mode"
00335                 g_flipbar_radios[i] = create_radio_button_item(NULL, _("Flip pages Left to Right")
00336                         , _("Flip pages like you would expect while using a computer."));
00337                 
00338                 break;
00339             }
00340             case 1:
00341             {
00342                 // The radio button "book mode"
00343                 g_flipbar_radios[i] = create_radio_button_item(g_flipbar_radios[0], _("Flip pages Right to Left")
00344                         , _("Flip pages like you would in a real book."));
00345                 
00346                 break;
00347             }
00348             default:
00349             {
00350                 // never happens
00351                 break;
00352             }
00353         }
00354 
00355         // Add signal handler.
00356         g_signal_connect_after(G_OBJECT(g_flipbar_radios[i]),
00357             "toggled",
00358             G_CALLBACK(on_flipbar_changed),
00359             (gpointer)i);
00360 
00361         gtk_box_pack_start(GTK_BOX(vbox), g_flipbar_radios[i], FALSE, FALSE, 0);
00362     }
00363 
00364     return top_level_vbox;
00365 }
00366 
00367 
00368 static void on_flipbar_changed(GtkWidget *widget, gpointer data)
00369 {
00370     int index = (int)data;
00371 
00372     g_assert( 0 <= index );
00373     g_assert( index < NUM_FLIPBAR_MODES );
00374 
00375     gboolean is_active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
00376 
00377     if (is_active == TRUE )
00378     {
00379         switch (index)
00380         {
00381             case 0:   // NOT INVERTED
00382                 g_cur_flipbar_settings.pageturn_inverted = FALSE;
00383                 break;
00384             case 1:     // INVERTED
00385                 g_cur_flipbar_settings.pageturn_inverted = TRUE;
00386                 break;
00387             default:
00388                 ERRORPRINTF("Invalid index [%d]", index);
00389                 break;
00390         }
00391     }
00392 }
00393 
00394 static void init_widgets_with_settings()
00395 {
00396     int i = 0;
00397     int to_be_activated = 0 ;
00398 
00399     if ( g_cur_flipbar_settings.pageturn_inverted == TRUE )
00400     {
00401         to_be_activated = 1;
00402     }
00403 
00404     for (i = 0; i < NUM_FLIPBAR_MODES; i++)
00405     {
00406         gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(g_flipbar_radios[i]),
00407                                       (i == to_be_activated) ? TRUE : FALSE );
00408     }
00409 }
00410 
Generated by  doxygen 1.6.2-20100208