Revision: 7177
Author:   ek.kato
Date:     Sun Jul  3 18:52:54 2011
Log:      * gtk2/candwin/horizontal-gtk.c
  - (index_button) : Use GtkEventBox instead of GtkButton.
  - (button_clicked) : Ditto.
  - (scale_label) : Ditto.
  - (candidate_window_init) : Ditto.
  - (assign_cellbutton) : Ditto.
  - (update_table_button) : Ditto.
  - (get_layout_x) : New.
  - (show_table) : Ditto.  Use gtk_widget_show_all() for the
    GtkEventBox.
  - (label_draw) : New.  For GTK+3, highlight the selected label.
  - (label_exposed) : New. For GTK+2.
  - (uim_cand_win_gtk_set_index) : Clear sub_window when not
    selected.

http://code.google.com/p/uim/source/detail?r=7177

Modified:
 /trunk/gtk2/candwin/horizontal-gtk.c

=======================================
--- /trunk/gtk2/candwin/horizontal-gtk.c        Sun Jun 19 19:04:03 2011
+++ /trunk/gtk2/candwin/horizontal-gtk.c        Sun Jul  3 18:52:54 2011
@@ -45,6 +45,7 @@
 #include <string.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <math.h>

 #include "../gtk2/immodule/caret-state-indicator.h"

@@ -140,7 +141,7 @@

 struct index_button {
   gint cand_index_in_page;
-  GtkButton *button;
+  GtkEventBox *button;
 };

 static void candidate_window_init(UIMCandidateWindow *cwin);
@@ -176,7 +177,7 @@
 static void candwin_show_page(gchar **str);
 static void str_parse(char *str);
 static void clear_button(struct index_button *idxbutton, gint cell_index);
-static void scale_label(GtkButton *button, double factor);
+static void scale_label(GtkEventBox *button, double factor);

 static void index_changed_cb(UIMCandidateWindow *cwin)
 {
@@ -230,8 +231,107 @@
   gtk_label_set_text(GTK_LABEL(cwin->num_label), label_str);
 }

+#if !GTK_CHECK_VERSION(2, 90, 0)
 static void
-button_clicked(GtkButton *button, gpointer data)
+get_layout_x(GtkLabel *label, gint *xp)
+{
+  GtkMisc *misc;
+  GtkWidget *widget;
+  gfloat xalign;
+  gint req_width, x;
+
+  misc = GTK_MISC(label);
+  widget = GTK_WIDGET(label);
+
+  if (gtk_widget_get_direction(widget) == GTK_TEXT_DIR_LTR)
+    xalign = misc->xalign;
+  else
+    xalign = 1.0 - misc->xalign;
+
+  req_width = widget->requisition.width;
+
+  x = floor(widget->allocation.x + (gint)misc->xpad +
+             xalign * (widget->allocation.width - req_width));
+
+  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
+    x = MAX(x, widget->allocation.x + misc->xpad);
+  else
+ x = MIN(x, widget->allocation.x + widget->allocation.width - misc->xpad);
+
+  if (xp)
+    *xp = x;
+}
+#endif
+#if GTK_CHECK_VERSION(2, 90, 0)
+static gboolean
+label_draw(GtkWidget *label, cairo_t *cr, gpointer data)
+{
+  UIMCandidateWindow *cwin = UIM_CANDIDATE_WINDOW(data);
+  struct index_button *selected;
+  GtkWidget *selected_label = NULL;
+
+  selected = cwin->selected;
+  if (selected)
+    selected_label = gtk_bin_get_child(GTK_BIN(selected->button));
+
+  if (label == selected_label) {
+    GdkRGBA *bg_color, *fg_color;
+    GtkStyleContext *context;
+    PangoLayout *layout;
+    gint x, y;
+    GtkStateFlags state;
+
+    layout = gtk_label_get_layout(GTK_LABEL(label));
+    gtk_label_get_layout_offsets(GTK_LABEL(label), &x, &y);
+
+    context = gtk_widget_get_style_context(label);
+
+    state = GTK_STATE_FLAG_SELECTED;
+ gtk_style_context_get (context, state, "background-color", &bg_color, "color
+", &fg_color, NULL);
+
+    cairo_save(cr);
+    gdk_cairo_set_source_rgba(cr, bg_color);
+    cairo_paint(cr);
+    cairo_restore(cr);
+    gdk_rgba_free(bg_color);
+    gdk_rgba_free(fg_color);
+
+
+    gtk_style_context_set_state (context, state);
+    gtk_render_layout (context, cr, x, y, layout);
+  }
+
+  return FALSE;
+}
+#else
+static gboolean
+label_exposed(GtkWidget *label, GdkEventExpose *event, gpointer data)
+{
+  UIMCandidateWindow *cwin = UIM_CANDIDATE_WINDOW(data);
+  struct index_button *selected;
+  GtkWidget *selected_label = NULL;
+
+  selected = cwin->selected;
+  if (selected)
+    selected_label = gtk_bin_get_child(GTK_BIN(selected->button));
+
+  if (label == selected_label) {
+    gint x;
+    get_layout_x(GTK_LABEL(label), &x);
+    gdk_draw_layout_with_colors(label->window,
+                      label->style->black_gc, x, 0,
+                      GTK_LABEL(label)->layout,
+                      &label->style->text[GTK_STATE_SELECTED],
+                      &label->style->bg[GTK_STATE_SELECTED]);
+  }
+
+  return FALSE;
+}
+#endif
+
+static void
+button_clicked(GtkEventBox *button, gpointer data)
 {
   UIMCandidateWindow *cwin = UIM_CANDIDATE_WINDOW(data);
   gint i;
@@ -240,11 +340,13 @@

   prev_selected = cwin->selected;
   if (prev_selected) {
-    gtk_button_set_relief(prev_selected->button, GTK_RELIEF_NONE);
+    GtkWidget *label = gtk_bin_get_child(GTK_BIN(prev_selected->button));
+    gtk_widget_unmap(label);
+    gtk_widget_map(label);
   }

   for (i = 0; i < (gint)cwin->buttons->len; i++) {
-    GtkButton *p;
+    GtkEventBox *p;
     struct index_button *idxbutton;
     idxbutton = g_ptr_array_index(cwin->buttons, i);
     if (!idxbutton) {
@@ -252,8 +354,10 @@
     }
     p = idxbutton->button;
     if (p == button) {
+      GtkWidget *label = gtk_bin_get_child(GTK_BIN(button));
       idx = idxbutton->cand_index_in_page;
-      gtk_button_set_relief(button, GTK_RELIEF_HALF);
+      gtk_widget_unmap(label);
+      gtk_widget_map(label);
       cwin->selected = idxbutton;
       break;
     }
@@ -291,7 +395,7 @@
   for (i = 0; i < (gint)cwin->buttons->len; i++) {
     if (cwin->buttons->pdata[i]) {
       g_free(cwin->buttons->pdata[i]);
-      /* GtkButton is destroyed by container */
+      /* GtkEventBox is destroyed by container */
     }
   }
   g_ptr_array_free(cwin->buttons, TRUE);
@@ -332,6 +436,7 @@
gtk_box_pack_start(GTK_BOX(cwin->vbox), cwin->scrolled_window, TRUE, TRUE, 0);

   cwin->view = gtk_table_new(1, DEFAULT_NR_CELLS, FALSE);
+  gtk_table_set_col_spacings(GTK_TABLE(cwin->view), 10);
   g_signal_connect(G_OBJECT(cwin->view), "destroy",
                   G_CALLBACK(cb_table_view_destroy), cwin->stores);
   cwin->viewport = gtk_viewport_new(NULL, NULL);
@@ -340,15 +445,24 @@
gtk_container_set_resize_mode(GTK_CONTAINER(cwin->viewport), GTK_RESIZE_PARENT);
   for (col = 0; col < DEFAULT_NR_CELLS; col++) {
     GtkWidget *button;
+    GtkWidget *label;
     struct index_button *idxbutton;

-    button = gtk_button_new_with_label("");
-    scale_label(GTK_BUTTON(button), PANGO_SCALE_LARGE);
-    g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), cwin);
+    button = gtk_event_box_new();
+    gtk_event_box_set_above_child(GTK_EVENT_BOX(button), TRUE);
+    label = gtk_label_new("");
+    gtk_container_add(GTK_CONTAINER(button), label);
+    scale_label(GTK_EVENT_BOX(button), PANGO_SCALE_LARGE);
+ g_signal_connect(button, "button-press-event", G_CALLBACK(button_clicked), cwin);
+#if GTK_CHECK_VERSION(2, 90, 0)
+    g_signal_connect_after(label, "draw", G_CALLBACK(label_draw), cwin);
+#else
+ g_signal_connect_after(label, "expose-event", G_CALLBACK(label_exposed), cwin);
+#endif
gtk_table_attach_defaults(GTK_TABLE(cwin->view), button, col, col + 1, 0, 1);
     idxbutton = g_malloc(sizeof(struct index_button));
     if (idxbutton) {
-      idxbutton->button = GTK_BUTTON(button);
+      idxbutton->button = GTK_EVENT_BOX(button);
       clear_button(idxbutton, col);
     }
     g_ptr_array_add(cwin->buttons, idxbutton);
@@ -379,7 +493,7 @@
   cwin->sub_window.active = FALSE;
 }

-static GtkButton*
+static GtkEventBox*
 assign_cellbutton(GPtrArray *buttons, gint cand_index, gint display_limit)
 {
   gint len;
@@ -388,14 +502,23 @@

   if (len <= cand_index) {
     GtkWidget *button;
-
-    button = gtk_button_new_with_label("");
-    scale_label(GTK_BUTTON(button), PANGO_SCALE_LARGE);
-    g_signal_connect(button, "clicked", G_CALLBACK(button_clicked), cwin);
+    GtkWidget *label;
+
+    button = gtk_event_box_new();
+    gtk_event_box_set_above_child(GTK_EVENT_BOX(button), TRUE);
+    label = gtk_label_new("");
+    gtk_container_add(GTK_CONTAINER(button), label);
+    scale_label(GTK_EVENT_BOX(button), PANGO_SCALE_LARGE);
+ g_signal_connect(button, "button-press-event", G_CALLBACK(button_clicked), cwin);
+#if GTK_CHECK_VERSION(2, 90, 0)
+    g_signal_connect_after(label, "draw", G_CALLBACK(label_draw), cwin);
+#else
+ g_signal_connect_after(label, "expose-event", G_CALLBACK(label_exposed), cwin);
+#endif
gtk_table_attach_defaults(GTK_TABLE(cwin->view), button, cand_index, cand_index + 1, 0, 1);
     idxbutton = g_malloc(sizeof(struct index_button));
     if (idxbutton) {
-      idxbutton->button = GTK_BUTTON(button);
+      idxbutton->button = GTK_EVENT_BOX(button);
       clear_button(idxbutton, cand_index);
       idxbutton->cand_index_in_page = cand_index;
     }
@@ -782,10 +905,11 @@
 static void
 uim_cand_win_gtk_set_index(UIMCandidateWindow *cwin, gint index)
 {
-  gint new_page;
+  gint new_page, prev_index;

   g_return_if_fail(UIM_IS_CANDIDATE_WINDOW(cwin));

+  prev_index = cwin->candidate_index;
   if (index >= (gint) cwin->nr_candidates)
     cwin->candidate_index = 0;
   else
@@ -796,14 +920,13 @@
   else
     new_page = cwin->page_index;

-  if (cwin->page_index != new_page) {
+  if (cwin->page_index != new_page)
     uim_cand_win_gtk_set_page(cwin, new_page);
-    uim_cand_win_gtk_show(cwin);
-  }
-
-  if (cwin->candidate_index >= 0) {
+
+  if (cwin->candidate_index >= 0 && cwin->need_hilite) {
     gint pos;
     struct index_button *idxbutton, *prev_selected;
+    GtkWidget *label;

     if (cwin->display_limit)
       pos = cwin->candidate_index % cwin->display_limit;
@@ -812,10 +935,14 @@

     idxbutton = g_ptr_array_index(cwin->buttons, pos);
     prev_selected = (gpointer)cwin->selected;
-    if (prev_selected) {
-      gtk_button_set_relief(prev_selected->button, GTK_RELIEF_NONE);
-    }
-    gtk_button_set_relief(idxbutton->button, GTK_RELIEF_HALF);
+    if (prev_selected && prev_index != cwin->candidate_index) {
+      label = gtk_bin_get_child(GTK_BIN(prev_selected->button));
+      gtk_widget_unmap(label);
+      gtk_widget_map(label);
+    }
+    label = gtk_bin_get_child(GTK_BIN(idxbutton->button));
+    gtk_widget_unmap(label);
+    gtk_widget_map(label);
     cwin->selected = idxbutton;

     /* show subwin */
@@ -842,13 +969,19 @@
       }
       free(annotation);
     }
+  } else {
+    cwin->selected = NULL;
+    if (cwin->sub_window.window) {
+      gtk_widget_hide(cwin->sub_window.window);
+      cwin->sub_window.active = FALSE;
+    }
   }

   update_label(cwin);
 }

 static void
-scale_label(GtkButton *button, double scale)
+scale_label(GtkEventBox *button, double scale)
 {
   GtkWidget *label;
   PangoAttrList *attrs = pango_attr_list_new();
@@ -864,13 +997,14 @@
 static void
 clear_button(struct index_button *idxbutton, gint cell_index)
 {
-  GtkButton *button;
+  GtkEventBox *button;
+  GtkWidget *label;

   idxbutton->cand_index_in_page = -1;
   button = idxbutton->button;
-  gtk_button_set_relief(button, GTK_RELIEF_NONE);
-  gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
-  gtk_button_set_label(button, "");
+
+  label = gtk_bin_get_child(GTK_BIN(button));
+  gtk_label_set_text(GTK_LABEL(label), "");
   scale_label(button, PANGO_SCALE_LARGE);
 }

@@ -904,21 +1038,21 @@
   while (has_next) {
     gchar *heading;
     gchar *cand_str;
-    GtkButton *button = NULL;
+    GtkEventBox *button = NULL;

     gtk_tree_model_get(model, &ti, COLUMN_HEADING, &heading,
         COLUMN_CANDIDATE, &cand_str, TERMINATOR);
     if (cand_str != NULL) {
       button = assign_cellbutton(buttons, cand_index, display_limit);
       if (button != NULL) {
-        gtk_button_set_relief(button, GTK_RELIEF_NONE);
-        gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
+        GtkWidget *label;
+       label = gtk_bin_get_child(GTK_BIN(button));
        if (heading && heading[0] != '\0') {
-         gchar *label = g_strdup_printf("%s: %s", heading, cand_str);
-         gtk_button_set_label(button, label);
-         g_free(label);
+         gchar *text = g_strdup_printf("%s %s", heading, cand_str);
+         gtk_label_set_text(GTK_LABEL(label), text);
+         g_free(text);
        } else {
-         gtk_button_set_label(button, cand_str);
+         gtk_label_set_text(GTK_LABEL(label), cand_str);
        }
        scale_label(button, PANGO_SCALE_LARGE);
       }
@@ -1157,13 +1291,13 @@
   gint col;

   for (col = 0; col < (gint)buttons->len; col++) {
-    GtkButton *button = NULL;
+    GtkEventBox *button = NULL;
     struct index_button *idxbutton;

     idxbutton = g_ptr_array_index(buttons, col);
     button = idxbutton->button;

-    gtk_widget_show(GTK_WIDGET(button));
+    gtk_widget_show_all(GTK_WIDGET(button));
   }
   gtk_widget_show(GTK_WIDGET(view));
 }

Reply via email to