[maemo-commits] [maemo-commits] r19217 - projects/haf/trunk/hildon-input-method-plugins-example/src

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Wed Aug 26 19:57:19 EEST 2009
Author: femorandeira
Date: 2009-08-26 19:57:16 +0300 (Wed, 26 Aug 2009)
New Revision: 19217

Modified:
   projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c
Log:
Improved the visual appearance. I added experimental support for changing the layout and using tap&hold. Once I have a clear idea for the user experience, I will begin to work on actually make it write something. As we don't have word completion or text selection, I wonder if I could simply listen to a bunch of signals from the text view and notify the client widget.

Modified: projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c
===================================================================
--- projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c	2009-08-26 15:55:47 UTC (rev 19216)
+++ projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c	2009-08-26 16:57:16 UTC (rev 19217)
@@ -19,20 +19,45 @@
         (G_TYPE_INSTANCE_GET_PRIVATE ((obj), HILDON_IM_EXAMPLE_FKB_TYPE,\
                                       HildonIMExampleFKBPrivate))
 
-static const gchar* layout_1[] = {"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", NULL};
-static const gchar* layout_2[] = {"a", "s", "d", "f", "g", "h", "j", "k", "l", "?", NULL};
-static const gchar* layout_3[] = {"z", "x", "c", "v", "b", "n", "m", ".", ",", "!", NULL};
-static const gchar* layout_4[] = {"↑", "1*?", " ", "Return", "←", "Close", NULL};
-static const gchar** keyboard_layout[] = {layout_1, layout_2, layout_3, layout_4, NULL};  
+/* ***** LAYOUTS ***** */
 
-/*
+/* I don't know why this doesn't work:
 static const gchar* keyboard_layout[][] = {{"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", NULL},
                                            {"a", "s", "d", "f", "g", "h", "j", "k", "l", NULL},
                                            {"z", "x", "c", "v", "b", "n", "m", NULL},
                                            NULL};
 */
 
+static const gchar* alpha_lower_1[] = {"q", "w", "e", "r", "t", "y", "u", "i", "o", "p", NULL};
+static const gchar* alpha_lower_2[] = {"a", "s", "d", "f", "g", "h", "j", "k", "l", ":", NULL};
+static const gchar* alpha_lower_3[] = {"z", "x", "c", "v", "b", "n", "m", ".", ",", ";", NULL};
+/* static const gchar* layout_4[] = {"↑", "1*?", " ", "Return", "←", "Close", NULL}; */
+static const gchar** alpha_lower[] = {alpha_lower_1,
+                                      alpha_lower_2,
+                                      alpha_lower_3, NULL};  
 
+static const gchar* alpha_upper_1[] = {"Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P", NULL};
+static const gchar* alpha_upper_2[] = {"A", "S", "D", "F", "G", "H", "J", "K", "L", "'", NULL};
+static const gchar* alpha_upper_3[] = {"+", "-", "*", "/", "\\", "%", "#", "¿", "¡", "§", NULL};
+static const gchar** alpha_upper[] = {alpha_upper_1,
+                                      alpha_upper_2,
+                                      alpha_upper_3, NULL};  
+
+static const gchar* special_lower_1[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", NULL};
+static const gchar* special_lower_2[] = {"á", "é", "í", "ó", "ú", "ñ", "ç", "ß", "æ", "\"", NULL};
+static const gchar* special_lower_3[] = {"+", "-", "*", "/", "\\", "%", "#", "", "", "", NULL};
+static const gchar** special_lower[] = {special_lower_1,
+                                        special_lower_2,
+                                        special_lower_3, NULL};  
+
+static const gchar* special_upper_1[] = {"1", "2", "3", "4", "5", "6", "7", "8", "9", "0", NULL};
+static const gchar* special_upper_2[] = {"Á", "É", "Í", "Ó", "Ú", "Ñ", "Ç", "ß", "Æ", "£", NULL};
+static const gchar* special_upper_3[] = {"(", ")", "[", "]", "{", "}", "<", ">", "€", "$", NULL};
+static const gchar** special_upper[] = {special_upper_1,
+                                        special_upper_2,
+                                        special_upper_3, NULL};  
+
+
 typedef struct
 {
   GtkContainerClass parent;
@@ -51,6 +76,16 @@
   HildonIMUI *ui;
   GtkWidget *window;
   GtkWidget *text_view;
+  
+  GtkWidget *keyboard_vbox;
+  
+  GtkWidget *shift_button;
+  GtkWidget *symbols_button;
+  GtkWidget *space_button;
+  GtkWidget *return_button;
+  GtkWidget *delete_button;
+  GtkWidget *close_button;
+  const gchar*** keyboard_layout;
 }
 HildonIMExampleFKBPrivate;
 
@@ -127,7 +162,7 @@
 /*
  * Internal functions
  */
-static GtkWidget* create_window (HildonIMExampleFKB *self);
+static void create_window (HildonIMExampleFKB *self);
 
 
 /*
@@ -366,7 +401,7 @@
   
   if (priv->window == NULL)
   {
-    priv->window = create_window(self);
+    create_window(self);
   }
   
 /*   gtk_window_fullscreen(priv->window); */
@@ -406,6 +441,62 @@
 }
 
 static void
+remove_children_from_container (GtkWidget *widget, gpointer data)
+{
+  GtkContainer *container;
+
+  if (!widget || !data)
+    return;
+  
+  container = (GtkContainer*)data;
+  gtk_container_remove (container, widget);
+}
+
+static void
+apply_keyboard_layout (HildonIMExampleFKB *self,
+                       const gchar** keyboard_layout[])
+{
+  HildonIMExampleFKBPrivate *priv;
+  gint i, j;
+
+  priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
+  
+  gtk_container_forall(GTK_CONTAINER(priv->keyboard_vbox),
+                       remove_children_from_container,
+                       GTK_CONTAINER(priv->keyboard_vbox));
+  
+  for (i = 0; keyboard_layout[i] != NULL; i++)
+  {
+    GtkWidget *hbox  = gtk_hbox_new(TRUE, 0);
+
+    for (j = 0; keyboard_layout[i][j] != NULL; j++)
+    {
+      GtkWidget *button = hildon_button_new_with_text (HILDON_SIZE_FINGER_HEIGHT,
+                                                       HILDON_BUTTON_ARRANGEMENT_VERTICAL,
+                                                       keyboard_layout[i][j], NULL);
+
+      gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
+
+      g_signal_connect(button, "clicked", G_CALLBACK(text_button_clicked), self);
+      
+      GtkWidget *menu = hildon_gtk_menu_new();
+      gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_menu_item_new_with_label("á"));
+      gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_menu_item_new_with_label("à"));
+      gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_menu_item_new_with_label("â"));
+      gtk_menu_shell_append(GTK_MENU_SHELL(menu), gtk_menu_item_new_with_label("æ"));
+      gtk_widget_tap_and_hold_setup(button, menu, NULL, 0); /* gtk_widget_tap_and_hold_menu_position_top ? */
+      gtk_widget_show_all (menu);
+    }
+
+    gtk_box_pack_start(GTK_BOX(priv->keyboard_vbox), hbox, FALSE, FALSE, 0);
+  }
+  
+  gtk_container_resize_children (GTK_CONTAINER(priv->keyboard_vbox));
+  gtk_container_resize_children (GTK_CONTAINER(priv->window));
+  priv->keyboard_layout = keyboard_layout;
+}
+
+static void
 delete_button_clicked (GtkButton *button, gpointer user_data)
 {
   /*
@@ -414,24 +505,60 @@
    */
 }
 
-static GtkWidget* create_window (HildonIMExampleFKB *self)
+static void
+shift_symbols_buttons_toggled (GtkToggleButton *togglebutton,
+                               gpointer user_data)
 {
+  HildonIMExampleFKB *self;
   HildonIMExampleFKBPrivate *priv;
 
+  g_return_if_fail (HILDON_IS_IM_EXAMPLE_FKB (user_data));
+  self = HILDON_IM_EXAMPLE_FKB(user_data);
   priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
   
-  GtkWidget* window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->symbols_button)))
+  {
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->shift_button)))
+    {
+      apply_keyboard_layout(self, special_upper);
+    }
+    else
+    {
+      apply_keyboard_layout(self, special_lower);
+    }
+  }
+  else
+  {
+    if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->shift_button)))
+    {
+      apply_keyboard_layout(self, alpha_upper);
+    }
+    else
+    {
+      apply_keyboard_layout(self, alpha_lower);
+    }
+  }
+}
+
+static void
+create_window (HildonIMExampleFKB *self)
+{
+  HildonIMExampleFKBPrivate *priv;
+
+  priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
   
-  gtk_window_set_type_hint(GTK_WINDOW(window), GDK_WINDOW_TYPE_HINT_DIALOG);
-  gtk_window_set_decorated(GTK_WINDOW(window), FALSE);
-  gtk_window_fullscreen(GTK_WINDOW(window));
+  priv->window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  
+  gtk_window_set_type_hint(GTK_WINDOW(priv->window), GDK_WINDOW_TYPE_HINT_DIALOG);
+  gtk_window_set_decorated(GTK_WINDOW(priv->window), FALSE);
+  gtk_window_fullscreen(GTK_WINDOW(priv->window));
   /*
   It is always rotated! :-(
   */
-  hildon_gtk_window_set_portrait_flags (GTK_WINDOW(window), 
+  hildon_gtk_window_set_portrait_flags (GTK_WINDOW(priv->window), 
                                         HILDON_PORTRAIT_MODE_SUPPORT);
   
-  GtkWidget *vbox, *parea;
+  GtkWidget *vbox, *parea, *hbox;
   
   vbox = gtk_vbox_new(FALSE, 5);
   
@@ -442,68 +569,79 @@
   
   parea = hildon_pannable_area_new();
   g_object_set(G_OBJECT(parea), "mov_mode", HILDON_MOVEMENT_MODE_VERT, NULL);
-  hildon_pannable_area_add_with_viewport (parea, priv->text_view);
+  hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA(parea), priv->text_view);
   
   gtk_box_pack_start(GTK_BOX(vbox), parea, TRUE, TRUE, 0);
   
-  gint i, j;
+  priv->keyboard_vbox = gtk_vbox_new(TRUE, 5);
+  gtk_box_pack_start(GTK_BOX(vbox), priv->keyboard_vbox, FALSE, FALSE, 0);
+  apply_keyboard_layout(self, alpha_lower);
   
-  for (i = 0; keyboard_layout[i] != NULL; i++)
-  {
-    GtkWidget *hbox  = gtk_hbox_new(FALSE, 0);
-    
-    for (j = 0; keyboard_layout[i][j] != NULL; j++)
-    {
-      GtkWidget *button = hildon_button_new_with_text (HILDON_SIZE_FINGER_HEIGHT,
-                                                       HILDON_BUTTON_ARRANGEMENT_VERTICAL,
-                                                       keyboard_layout[i][j], NULL);
-      
-      gint screen_width = gdk_screen_width();
-            
-      gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
-      if (g_strcmp0(keyboard_layout[i][j], "↑") == 0)
-      {
-        /* uppercase/lowercase */
-        gtk_widget_set_size_request(button, screen_width*0.15, 70);
-      }
-      else if (g_strcmp0(keyboard_layout[i][j], "1*?") == 0)
-      {
-        /* symbols */
-        gtk_widget_set_size_request(button, screen_width*0.15, 70);  
-      }
-      else if (g_strcmp0(keyboard_layout[i][j], " ") == 0)
-      {
-        /* uppercase/lowercase */
-        gtk_widget_set_size_request(button, screen_width*0.4, 70); 
-        g_signal_connect(button, "clicked", G_CALLBACK(text_button_clicked), self);
-      }
-      else if (g_strcmp0(keyboard_layout[i][j], "Return") == 0)
-      {
-        /* uppercase/lowercase */
-        gtk_widget_set_size_request(button, screen_width*0.15, 70);
-      }
-      else if (g_strcmp0(keyboard_layout[i][j], "←") == 0)
-      {
-        /* delete */
-        gtk_widget_set_size_request(button, screen_width*0.2, 70);
-        g_signal_connect(button, "clicked", G_CALLBACK(delete_button_clicked), self);
-      }
-      else if (g_strcmp0(keyboard_layout[i][j], "Close") == 0)
-      {
-        /* uppercase/lowercase */
-        gtk_widget_set_size_request(button, screen_width*0.1, 70);
-      }
-      else
-      {
-        /* a regular character button */
-        g_signal_connect(button, "clicked", G_CALLBACK(text_button_clicked), self);
-      }
-    }
-    
-    gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
-  }
+  gint screen_width = gdk_screen_width();
+
+  hbox = gtk_hbox_new(FALSE, 0);
   
-  gtk_container_add (GTK_CONTAINER(window), vbox);
+  /* Shif button */
   
-  return window;
+  priv->shift_button = hildon_gtk_toggle_button_new(HILDON_SIZE_FINGER_HEIGHT);
+  hildon_button_set_image(HILDON_BUTTON(priv->shift_button),
+                          gtk_image_new_from_icon_name("keyboard_move_up", -1));
+  gtk_widget_set_size_request(priv->shift_button, screen_width*0.15, 70);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->shift_button, TRUE, TRUE, 0);
+  g_signal_connect(priv->shift_button, "toggled",
+                   G_CALLBACK(shift_symbols_buttons_toggled), self);
+
+  /* Symbols button */
+  
+  priv->symbols_button = hildon_gtk_toggle_button_new (HILDON_SIZE_FINGER_HEIGHT);
+  gtk_button_set_label(GTK_BUTTON(priv->symbols_button), "1*?");
+  gtk_widget_set_size_request(priv->symbols_button, screen_width*0.15, 70);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->symbols_button, TRUE, TRUE, 0);
+  g_signal_connect(priv->shift_button, "toggled",
+                   G_CALLBACK(shift_symbols_buttons_toggled), self);
+
+  /* Space button */
+  
+  priv->space_button = hildon_button_new_with_text (HILDON_SIZE_FINGER_HEIGHT,
+                                                    HILDON_BUTTON_ARRANGEMENT_VERTICAL,
+                                                    " ", NULL);
+  gtk_widget_set_size_request(priv->space_button, screen_width*0.3, 70);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->space_button, TRUE, TRUE, 0);
+
+  /* Return button */
+  
+  priv->return_button = hildon_button_new(HILDON_SIZE_FINGER_HEIGHT,
+                                          HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+  hildon_button_set_image(HILDON_BUTTON(priv->return_button),
+                          gtk_image_new_from_icon_name("keyboard_enter",
+                                                       -1));
+  gtk_widget_set_size_request(priv->return_button, screen_width*0.15, 70);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->return_button, TRUE, TRUE, 0);
+
+  /* Delete button */
+  
+  priv->delete_button = hildon_button_new(HILDON_SIZE_FINGER_HEIGHT,
+                                          HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+  hildon_button_set_image(HILDON_BUTTON(priv->delete_button),
+                          gtk_image_new_from_icon_name("general_backspace",
+                                                       -1));
+  gtk_widget_set_size_request(priv->delete_button, screen_width*0.15, 70);
+  g_signal_connect(priv->delete_button, "clicked", G_CALLBACK(delete_button_clicked), self);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->delete_button, TRUE, TRUE, 0);
+
+  /* Close button */
+  
+  priv->close_button = hildon_button_new(HILDON_SIZE_FINGER_HEIGHT,
+                                         HILDON_BUTTON_ARRANGEMENT_VERTICAL);
+  hildon_button_set_image(HILDON_BUTTON(priv->close_button),
+                          gtk_image_new_from_icon_name("keyboard_close",
+                                                       -1));
+  gtk_widget_set_size_request(priv->close_button, screen_width*0.1, 70);
+  gtk_box_pack_start(GTK_BOX(hbox), priv->close_button, TRUE, TRUE, 0);
+  
+  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+  
+  gtk_container_add (GTK_CONTAINER(priv->window), vbox);
+  
+  gtk_container_resize_children (GTK_CONTAINER(priv->window));
 }

More information about the maemo-commits mailing list