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));
}