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

From: subversion at stage.maemo.org subversion at stage.maemo.org
Date: Fri Aug 28 19:50:33 EEST 2009
Author: femorandeira
Date: 2009-08-28 19:50:31 +0300 (Fri, 28 Aug 2009)
New Revision: 19246

Modified:
   projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c
Log:
Many changes. I added surrounding amnagement and the hability to enter and delete text in TextViews and Entries. I still have to change how the different layouts are set; the best way seems to be using a Notebook without tabs.

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-28 15:54:42 UTC (rev 19245)
+++ projects/haf/trunk/hildon-input-method-plugins-example/src/hildon-im-example-fkb.c	2009-08-28 16:50:31 UTC (rev 19246)
@@ -38,20 +38,20 @@
 
 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_3[] = {"Z", "X", "C", "V", "B", "N", "M", "?", "!", "_", 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_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_2[] = {"Á", "É", "Í", "Ó", "Ú", "Ñ", "Ç", "Æ", "_", "£", NULL};
 static const gchar* special_upper_3[] = {"(", ")", "[", "]", "{", "}", "<", ">", "€", "$", NULL};
 static const gchar** special_upper[] = {special_upper_1,
                                         special_upper_2,
@@ -77,8 +77,16 @@
   GtkWidget *window;
   GtkWidget *text_view;
   
+  gint saved_offset;
+  
+  GtkWidget *vbox;
   GtkWidget *keyboard_vbox;
   
+  GtkWidget *alpha_lower;
+  GtkWidget *alpha_upper;
+  GtkWidget *special_lower;
+  GtkWidget *special_upper;
+  
   GtkWidget *shift_button;
   GtkWidget *symbols_button;
   GtkWidget *space_button;
@@ -103,6 +111,9 @@
 
 static void hildon_im_example_fkb_enable (HildonIMPlugin *plugin, gboolean init);
 static void hildon_im_example_fkb_disable                   (HildonIMPlugin *plugin);
+static void hildon_im_example_fkb_surrounding_received      (HildonIMPlugin *plugin,
+                                                             const gchar *surrounding,
+                                                             gint offset);
 /*
 static void hildon_im_example_fkb_settings_changed          (HildonIMPlugin *plugin,
                                                              const gchar *key,
@@ -133,9 +144,6 @@
                                                              guint hardware_keycode);
 static void hildon_im_example_fkb_transition                (HildonIMPlugin *plugin,
                                                              gboolean from);
-static void hildon_im_example_fkb_surrounding_received      (HildonIMPlugin *plugin,
-                                                             const gchar *surrounding,
-                                                             gint offset);
 static void hildon_im_example_fkb_button_activated          (HildonIMPlugin *plugin,
                                                              HildonIMButton button,
                                                              gboolean long_press);
@@ -268,6 +276,7 @@
 {
   iface->enable = hildon_im_example_fkb_enable;
   iface->disable = hildon_im_example_fkb_disable;
+  iface->surrounding_received = hildon_im_example_fkb_surrounding_received;
   /*
   iface->settings_changed = hildon_im_example_fkb_settings_changed;
   iface->language_settings_changed = hildon_im_example_fkb_language_settings_changed;
@@ -288,7 +297,6 @@
   iface->select_region = hildon_im_example_fkb_select_region;
   iface->key_event = hildon_im_example_fkb_key_event;
   iface->transition = hildon_im_example_fkb_transition;
-  iface->surrounding_received = hildon_im_example_fkb_surrounding_received;
   iface->button_activated = hildon_im_example_fkb_button_activated;
   iface->preedit_committed = hildon_im_example_fkb_preedit_committed;
   */
@@ -315,6 +323,14 @@
   object_class->finalize      = hildon_im_example_fkb_finalize;
   
   /* install properties and signals as needed */
+  
+  g_object_class_install_property(object_class, HILDON_IM_PROP_UI,
+                                  g_param_spec_object (HILDON_IM_PROP_UI_DESCRIPTION, 
+                                                       HILDON_IM_PROP_UI_DESCRIPTION,
+                                                       "UI that uses plugin",
+                                                       HILDON_IM_TYPE_UI,
+                                                       G_PARAM_READWRITE
+                                                       | G_PARAM_CONSTRUCT_ONLY));
 }
 
 static void
@@ -326,6 +342,10 @@
   priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
   
   priv->window = NULL;
+  priv->alpha_lower = NULL;
+  priv->alpha_upper = NULL;
+  priv->special_lower = NULL;
+  priv->special_upper = NULL;
 }
 
 static void 
@@ -404,8 +424,13 @@
     create_window(self);
   }
   
-/*   gtk_window_fullscreen(priv->window); */
-  gtk_widget_show_all(GTK_WIDGET(priv->window));
+  priv->saved_offset = 0;
+  
+  hildon_im_ui_send_communication_message(priv->ui,
+                                          HILDON_IM_CONTEXT_REQUEST_SURROUNDING_FULL);
+  
+  gtk_window_fullscreen(GTK_WINDOW(priv->window));
+  gtk_widget_show_all(priv->window);
 
   gdk_window_set_transient_for(GTK_WIDGET(priv->window)->window,
                                gtk_widget_get_root_window(GTK_WIDGET(priv->window)));
@@ -426,18 +451,83 @@
 }
 
 static void
+hildon_im_example_fkb_surrounding_received(HildonIMPlugin *plugin,
+                                           const gchar *surrounding,
+                                           gint offset)
+{
+  HildonIMExampleFKB *self;
+  HildonIMExampleFKBPrivate *priv;
+  GtkTextBuffer *buffer;
+  GtkTextIter cursor_iter;
+
+  self = HILDON_IM_EXAMPLE_FKB(plugin);
+  priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
+
+  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view));
+
+  /* I don't know why, but the view doesn't reflect the changes immediately */
+  gtk_text_buffer_set_text(buffer, surrounding, -1);
+  gtk_text_buffer_get_iter_at_offset(buffer, &cursor_iter, offset);
+  gtk_text_buffer_place_cursor(buffer, &cursor_iter);
+  
+  priv->saved_offset = offset;
+}
+
+static gboolean
+textview_button_release_cb(GtkWidget *textview, GdkEventButton *event, gpointer data)
+{
+  HildonIMExampleFKB *self;
+  HildonIMExampleFKBPrivate *priv;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  gint offset;
+  
+  g_return_val_if_fail (HILDON_IS_IM_EXAMPLE_FKB (data), FALSE);
+  self = HILDON_IM_EXAMPLE_FKB(data);
+  priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
+
+  /* update the cursor position */
+  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view));
+  gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+                                   gtk_text_buffer_get_selection_bound(buffer));
+  offset = gtk_text_iter_get_offset(&iter);
+
+  if (hildon_im_ui_get_commit_mode(priv->ui) == HILDON_IM_COMMIT_REDIRECT)
+  {
+    hildon_im_ui_send_surrounding_offset(priv->ui,
+                                         TRUE,
+                                         offset - priv->saved_offset);
+    priv->saved_offset = offset;
+  }
+  
+  return FALSE;
+}
+
+static void
 text_button_clicked (GtkButton *button, gpointer user_data)
 {
   HildonIMExampleFKB *self;
   HildonIMExampleFKBPrivate *priv;
+  GtkTextBuffer *buffer;
+  GtkTextIter iter;
+  const gchar *text;
 
   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);
 
+  text = hildon_button_get_title(HILDON_BUTTON(button));
   gtk_text_buffer_insert_at_cursor(gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view)),
-                                   hildon_button_get_title(HILDON_BUTTON(button)),
-                                   strlen(hildon_button_get_title(HILDON_BUTTON(button))));
+                                   text, strlen(text));
+  
+  if (hildon_im_ui_get_commit_mode(priv->ui) == HILDON_IM_COMMIT_REDIRECT)
+  {
+    hildon_im_ui_send_utf8(priv->ui, text);
+    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view));
+    gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+                                     gtk_text_buffer_get_selection_bound(buffer));
+    priv->saved_offset = gtk_text_iter_get_offset(&iter);
+  }
 }
 
 static void
@@ -452,19 +542,13 @@
   gtk_container_remove (container, widget);
 }
 
-static void
-apply_keyboard_layout (HildonIMExampleFKB *self,
-                       const gchar** keyboard_layout[])
+static GtkWidget*
+get_keyboard_layout (HildonIMExampleFKB *self,
+                     const gchar** keyboard_layout[])
 {
-  HildonIMExampleFKBPrivate *priv;
+  GtkWidget *vbox = gtk_vbox_new(TRUE, 0);
   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);
@@ -477,40 +561,106 @@
 
       gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
 
-      g_signal_connect(button, "clicked", G_CALLBACK(text_button_clicked), self);
-      
+      g_signal_connect(button, "pressed", 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_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_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
   }
+
+  return vbox;
+}
+
+static void
+apply_keyboard_layout (HildonIMExampleFKB *self,
+                       GtkWidget *layout)
+{
+  HildonIMExampleFKBPrivate *priv;
+
+  priv = HILDON_IM_EXAMPLE_FKB_GET_PRIVATE(self);
   
-  gtk_container_resize_children (GTK_CONTAINER(priv->keyboard_vbox));
+  gtk_container_forall(GTK_CONTAINER(priv->keyboard_vbox),
+                       remove_children_from_container,
+                       GTK_CONTAINER(priv->keyboard_vbox));
+
+  gtk_box_pack_start(GTK_BOX(priv->keyboard_vbox), layout, FALSE, FALSE, 0);
+  
+  gtk_widget_show_all (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)
 {
-  /*
-   * 
-gtk_text_buffer_delete
-   */
+  HildonIMExampleFKB *self;
+  HildonIMExampleFKBPrivate *priv;
+  GtkTextIter iter;
+  GtkTextBuffer *buffer;
+
+  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);
+  
+  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view));
+  gtk_text_buffer_get_iter_at_mark(buffer, &iter, gtk_text_buffer_get_insert(buffer));
+  gtk_text_buffer_backspace (buffer, &iter, TRUE, TRUE);
+  
+  if (hildon_im_ui_get_commit_mode(priv->ui) == HILDON_IM_COMMIT_REDIRECT)
+  {
+    hildon_im_ui_send_communication_message(priv->ui,
+                                            HILDON_IM_CONTEXT_HANDLE_BACKSPACE);
+    gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+                                     gtk_text_buffer_get_selection_bound(buffer));
+    priv->saved_offset = gtk_text_iter_get_offset(&iter);
+  }
 }
 
 static void
+return_button_clicked (GtkButton *button, gpointer user_data)
+{
+  HildonIMExampleFKB *self;
+  HildonIMExampleFKBPrivate *priv;
+  GtkTextIter iter;
+  GtkTextBuffer *buffer;
+
+  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);
+  
+  gtk_text_buffer_insert_at_cursor(gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view)),
+                                   "\n", 1);
+  
+  if (hildon_im_ui_get_commit_mode(priv->ui) == HILDON_IM_COMMIT_REDIRECT)
+  {
+    hildon_im_ui_send_utf8(priv->ui, "\n");
+    buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(priv->text_view));
+    gtk_text_buffer_get_iter_at_mark(buffer, &iter,
+                                     gtk_text_buffer_get_selection_bound(buffer));
+    priv->saved_offset = gtk_text_iter_get_offset(&iter);
+  }
+}
+
+static void
+close_fkb (GtkButton *button, gpointer user_data)
+{
+  hildon_im_example_fkb_disable(HILDON_IM_PLUGIN (user_data));
+}
+
+static void
 shift_symbols_buttons_toggled (GtkToggleButton *togglebutton,
                                gpointer user_data)
 {
   HildonIMExampleFKB *self;
   HildonIMExampleFKBPrivate *priv;
+  
+  /* TODO implement this with a Notebook without tabs
+   * toggling the selectors just changes the tab that is being shown */
 
   g_return_if_fail (HILDON_IS_IM_EXAMPLE_FKB (user_data));
   self = HILDON_IM_EXAMPLE_FKB(user_data);
@@ -520,22 +670,22 @@
   {
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->shift_button)))
     {
-      apply_keyboard_layout(self, special_upper);
+      apply_keyboard_layout(self, priv->special_upper);
     }
     else
     {
-      apply_keyboard_layout(self, special_lower);
+      apply_keyboard_layout(self, priv->special_lower);
     }
   }
   else
   {
     if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->shift_button)))
     {
-      apply_keyboard_layout(self, alpha_upper);
+      apply_keyboard_layout(self, priv->alpha_upper);
     }
     else
     {
-      apply_keyboard_layout(self, alpha_lower);
+      apply_keyboard_layout(self, priv->alpha_lower);
     }
   }
 }
@@ -558,25 +708,27 @@
   hildon_gtk_window_set_portrait_flags (GTK_WINDOW(priv->window), 
                                         HILDON_PORTRAIT_MODE_SUPPORT);
   
-  GtkWidget *vbox, *parea, *hbox;
+  GtkWidget *parea, *hbox;
   
-  vbox = gtk_vbox_new(FALSE, 5);
+  priv->vbox = gtk_vbox_new(FALSE, 5);
   
   priv->text_view = hildon_text_view_new();
   gtk_widget_set_name(priv->text_view, "him-textview");
   gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(priv->text_view), GTK_WRAP_WORD_CHAR);
   gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(priv->text_view), TRUE);
   
+  g_signal_connect_after(G_OBJECT(priv->text_view), "button-press-event",
+                         G_CALLBACK(textview_button_release_cb), self);
+  
   parea = hildon_pannable_area_new();
   g_object_set(G_OBJECT(parea), "mov_mode", HILDON_MOVEMENT_MODE_VERT, NULL);
   hildon_pannable_area_add_with_viewport (HILDON_PANNABLE_AREA(parea), priv->text_view);
   
-  gtk_box_pack_start(GTK_BOX(vbox), parea, TRUE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(priv->vbox), parea, TRUE, TRUE, 0);
   
   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);
-  
+  gtk_box_pack_start(GTK_BOX(priv->vbox), priv->keyboard_vbox, FALSE, FALSE, 0);
+
   gint screen_width = gdk_screen_width();
 
   hbox = gtk_hbox_new(FALSE, 0);
@@ -584,8 +736,7 @@
   /* Shif button */
   
   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_button_set_label(GTK_BUTTON(priv->shift_button), "↑");
   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",
@@ -597,7 +748,7 @@
   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_signal_connect(priv->symbols_button, "toggled",
                    G_CALLBACK(shift_symbols_buttons_toggled), self);
 
   /* Space button */
@@ -607,6 +758,7 @@
                                                     " ", 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);
+  g_signal_connect(priv->space_button, "pressed", G_CALLBACK(text_button_clicked), self);
 
   /* Return button */
   
@@ -617,6 +769,7 @@
                                                        -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);
+  g_signal_connect(priv->return_button, "pressed", G_CALLBACK(return_button_clicked), self);
 
   /* Delete button */
   
@@ -626,10 +779,11 @@
                           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);
+  g_signal_connect(priv->delete_button, "pressed", G_CALLBACK(delete_button_clicked), self);
 
-  /* Close button */
+  /* Close button
+   * TODO place it somewhere else */
   
   priv->close_button = hildon_button_new(HILDON_SIZE_FINGER_HEIGHT,
                                          HILDON_BUTTON_ARRANGEMENT_VERTICAL);
@@ -638,10 +792,23 @@
                                                        -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);
+  g_signal_connect(priv->close_button, "pressed", G_CALLBACK(close_fkb), self);
   
-  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
+  gtk_box_pack_start(GTK_BOX(priv->vbox), hbox, FALSE, FALSE, 0);
   
-  gtk_container_add (GTK_CONTAINER(priv->window), vbox);
+  gtk_container_add (GTK_CONTAINER(priv->window), priv->vbox);
   
-  gtk_container_resize_children (GTK_CONTAINER(priv->window));
+  /* now we create the different layouts
+   * if this is too slow, we could do it on demand */
+  priv->alpha_lower = get_keyboard_layout(self, alpha_lower);
+  priv->alpha_upper = get_keyboard_layout(self, alpha_upper);
+  priv->special_lower = get_keyboard_layout(self, special_lower);
+  priv->special_upper = get_keyboard_layout(self, special_upper);
+  
+  g_object_ref(priv->alpha_lower);
+  g_object_ref(priv->alpha_upper);
+  g_object_ref(priv->special_lower);
+  g_object_ref(priv->special_upper);
+  
+  apply_keyboard_layout(self, priv->alpha_lower);
 }

More information about the maemo-commits mailing list