Revision: 7144
Author: ek.kato
Date: Thu Jun 16 23:54:38 2011
Log: - Implement an experimental horizontal candidate window for GTK+
immodule.
* gtk2/immodule/Makefile.am (IM_UIM_SOURCES) : Add
uim-cand-win-horizontal-gtk.c uim-cand-win-horizontal-gtk.
* gtk3/immodule/Makefile.am (IM_UIM_SOURCES) : Ditto.
* gtk2/immodule/uim-cand-win-horizontal-gtk.c : Copied from
uim-cand-win-tbl-gtk.c. Modified for the single row table.
* gtk2/immodule/uim-cand-win-horizontal-gtk.h : Copied from
uim-cand-win-tbl-gtk.h.
* gtk2/immodule/uim-cand-win-gtk.h
- (_UIMCandWinGtkClass) : Add create_sub_window and
layout_sub_window members and make
uim_cand_win_gtk_create_sub_window and
uim_cand_win_gtk_layout_sub_window public.
* gtk2/immodule/uim-cand-win-gtk.c
- (uim_cand_win_gtk_create_sub_window) : Make public and call
member function of the class.
- (uim_cand_win_gtk_layout_sub_window) : Ditto.
- (uim_cand_win_gtk_real_create_sub_window) : Rename from
uim_cand_win_gtk_create_sub_window.
- (uim_cand_win_gtk_real_layout_sub_window) : Rename from
uim_cand_win_gtk_layout_sub_window.
- (uim_cand_win_gtk_class_init) : Set create_sub_window and
layout_subwindow.
- (uim_cand_win_gtk_layout) : Change positioning when right side
of the candidate window exceeds the display's limit.
* gtk2/immodule/gtk-im-uim.c
- Include "uim-cand-win-horizontal-gtk.h".
- (im_uim_create_cand_win_gtk) : Check "uim-candwin-horizontal"
prefix for uim-candwin-prog.
http://code.google.com/p/uim/source/detail?r=7144
Added:
/trunk/gtk2/immodule/uim-cand-win-horizontal-gtk.c
/trunk/gtk2/immodule/uim-cand-win-horizontal-gtk.h
Modified:
/trunk/gtk2/immodule/Makefile.am
/trunk/gtk2/immodule/gtk-im-uim.c
/trunk/gtk2/immodule/uim-cand-win-gtk.c
/trunk/gtk2/immodule/uim-cand-win-gtk.h
/trunk/gtk3/immodule/Makefile.am
=======================================
--- /dev/null
+++ /trunk/gtk2/immodule/uim-cand-win-horizontal-gtk.c Thu Jun 16 23:54:38
2011
@@ -0,0 +1,603 @@
+/*
+
+ copyright (c) 2003-2011 uim Project http://code.google.com/p/uim/
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+*/
+
+#include <config.h>
+
+#include "uim-cand-win-horizontal-gtk.h"
+#include <string.h>
+#include <stdlib.h>
+#include <uim/uim.h>
+#include <uim/uim-scm.h>
+
+#define DEFAULT_MIN_WINDOW_WIDTH 60
+
+enum {
+ TERMINATOR = -1,
+ COLUMN_HEADING,
+ COLUMN_CANDIDATE,
+ COLUMN_ANNOTATION,
+ LISTSTORE_NR_COLUMNS
+};
+
+#define DEFAULT_NR_CELLS 10
+
+struct index_button {
+ gint cand_index_in_page;
+ GtkButton *button;
+};
+
+static void uim_cand_win_horizontal_gtk_init(UIMCandWinHorizontalGtk
*cwin);
+static void uim_cand_win_horizontal_gtk_class_init(UIMCandWinGtkClass
*klass);
+static void uim_cand_win_horizontal_gtk_dispose(GObject *obj);
+static void button_clicked(GtkButton *button, gpointer data);
+static void clear_button(struct index_button *idxbutton, gint cell_index);
+static void show_table(GtkTable *view, GPtrArray *buttons);
+static void scale_label(GtkButton *button, double factor);
+
+
+static GType cand_win_horizontal_type = 0;
+static GTypeInfo const object_info = {
+ sizeof (UIMCandWinHorizontalGtkClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) uim_cand_win_horizontal_gtk_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (UIMCandWinHorizontalGtk),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) uim_cand_win_horizontal_gtk_init,
+};
+
+static GtkWindowClass *parent_class = NULL;
+
+GType
+uim_cand_win_horizontal_gtk_get_type(void)
+{
+ if (!cand_win_horizontal_type)
+ cand_win_horizontal_type =
g_type_register_static(UIM_TYPE_CAND_WIN_GTK, "UIMCandWinHorizontalGtk",
+ &object_info, (GTypeFlags)0);
+ return cand_win_horizontal_type;
+}
+
+GType
+uim_cand_win_horizontal_gtk_register_type(GTypeModule *module)
+{
+ if (!cand_win_horizontal_type)
+ cand_win_horizontal_type = g_type_module_register_type(module,
+ UIM_TYPE_CAND_WIN_GTK,
+ "UIMCandWinHorizontalGtk",
+ &object_info, 0);
+ return cand_win_horizontal_type;
+}
+
+static void
+uim_cand_win_horizontal_gtk_class_init (UIMCandWinGtkClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class->dispose = uim_cand_win_horizontal_gtk_dispose;
+
+ klass->set_index = (void (*)(UIMCandWinGtk *,
gint))uim_cand_win_horizontal_gtk_set_index;
+ klass->set_page = (void (*)(UIMCandWinGtk *,
gint))uim_cand_win_horizontal_gtk_set_page;
+ klass->create_sub_window = (void (*)(UIMCandWinGtk
*))uim_cand_win_horizontal_gtk_create_sub_window;
+ klass->layout_sub_window = (void (*)(UIMCandWinGtk
*))uim_cand_win_horizontal_gtk_layout_sub_window;
+}
+
+static void
+uim_cand_win_horizontal_gtk_init (UIMCandWinHorizontalGtk *horizontal_cwin)
+{
+ gint col;
+ GtkWidget *viewport;
+ UIMCandWinGtk *cwin;
+
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+
+ horizontal_cwin->buttons = g_ptr_array_new();
+ horizontal_cwin->selected = NULL;
+
+ gtk_widget_destroy(cwin->view);
+ cwin->view = gtk_table_new(1, DEFAULT_NR_CELLS, FALSE);
+ viewport = gtk_viewport_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(viewport), cwin->view);
+ gtk_container_add(GTK_CONTAINER(cwin->scrolled_window), viewport);
+ gtk_container_set_resize_mode(GTK_CONTAINER(viewport),
GTK_RESIZE_PARENT);
+ for (col = 0; col < DEFAULT_NR_CELLS; col++) {
+ GtkWidget *button;
+ 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),
horizontal_cwin);
+ 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);
+ clear_button(idxbutton, col);
+ }
+ g_ptr_array_add(horizontal_cwin->buttons, idxbutton);
+ }
+
+ gtk_widget_show_all(cwin->view);
+ gtk_widget_show(viewport);
+
+ gtk_widget_set_size_request(cwin->num_label, DEFAULT_MIN_WINDOW_WIDTH,
-1);
+ gtk_window_set_default_size(GTK_WINDOW(cwin), DEFAULT_MIN_WINDOW_WIDTH,
-1);
+ gtk_window_set_resizable(GTK_WINDOW(cwin), FALSE);
+}
+
+static void
+button_clicked(GtkButton *button, gpointer data)
+{
+ UIMCandWinHorizontalGtk *horizontal_cwin = data;
+ UIMCandWinGtk *cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+ gint i;
+ gint idx = -1;
+ struct index_button *prev_selected;
+
+ prev_selected = horizontal_cwin->selected;
+ if (prev_selected) {
+ gtk_button_set_relief(prev_selected->button, GTK_RELIEF_NONE);
+ }
+
+ for (i = 0; i < (gint)horizontal_cwin->buttons->len; i++) {
+ GtkButton *p;
+ struct index_button *idxbutton;
+ idxbutton = g_ptr_array_index(horizontal_cwin->buttons, i);
+ if (!idxbutton) {
+ continue;
+ }
+ p = idxbutton->button;
+ if (p == button) {
+ idx = idxbutton->cand_index_in_page;
+ gtk_button_set_relief(button, GTK_RELIEF_HALF);
+ horizontal_cwin->selected = idxbutton;
+ break;
+ }
+ }
+ if (idx >= 0 && cwin->display_limit) {
+ if (idx >= (gint)cwin->display_limit) {
+ idx %= cwin->display_limit;
+ }
+ cwin->candidate_index = cwin->page_index * cwin->display_limit + idx;
+ } else {
+ cwin->candidate_index = idx;
+ }
+ if (cwin->candidate_index >= (gint)cwin->nr_candidates) {
+ cwin->candidate_index = -1;
+ }
+
+ g_signal_emit_by_name(G_OBJECT(cwin), "index-changed");
+}
+
+static void
+uim_cand_win_horizontal_gtk_dispose (GObject *obj)
+{
+ UIMCandWinHorizontalGtk *horizontal_cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(obj));
+
+ horizontal_cwin = UIM_CAND_WIN_HORIZONTAL_GTK(obj);
+
+ if (horizontal_cwin->buttons) {
+ guint i;
+ for (i = 0; i < horizontal_cwin->buttons->len; i++) {
+ g_free(horizontal_cwin->buttons->pdata[i]);
+ /* GtkButton is destroyed by container */
+ }
+ g_ptr_array_free(horizontal_cwin->buttons, TRUE);
+ horizontal_cwin->buttons = NULL;
+ }
+ horizontal_cwin->selected = NULL;
+
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ G_OBJECT_CLASS (parent_class)->dispose(obj);
+}
+
+UIMCandWinHorizontalGtk *
+uim_cand_win_horizontal_gtk_new (void)
+{
+ GObject *obj = g_object_new(UIM_TYPE_CAND_WIN_HORIZONTAL_GTK,
+ "type", GTK_WINDOW_POPUP,
+ NULL);
+
+ return UIM_CAND_WIN_HORIZONTAL_GTK(obj);
+}
+
+static GtkButton*
+assign_cellbutton(UIMCandWinHorizontalGtk *horizontal_cwin,
+ gchar *heading, gint cand_index, gint display_limit)
+{
+ struct index_button *idxbutton;
+ int len;
+ GPtrArray *buttons;
+
+ buttons = horizontal_cwin->buttons;
+ len = buttons->len;
+
+ 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),
horizontal_cwin);
+
gtk_table_attach_defaults(GTK_TABLE(UIM_CAND_WIN_GTK(horizontal_cwin)->view),
button, cand_index, cand_index + 1, 0, 1);
+ idxbutton = g_malloc(sizeof(struct index_button));
+ if (idxbutton) {
+ idxbutton->button = GTK_BUTTON(button);
+ clear_button(idxbutton, cand_index);
+ idxbutton->cand_index_in_page = cand_index;
+ }
+ g_ptr_array_add(horizontal_cwin->buttons, idxbutton);
+ } else {
+ idxbutton = g_ptr_array_index(buttons, cand_index);
+ idxbutton->cand_index_in_page = cand_index;
+ }
+
+ return idxbutton->button;
+}
+
+void
+uim_cand_win_horizontal_gtk_set_index(UIMCandWinHorizontalGtk
*horizontal_cwin, gint index)
+{
+ gint new_page;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(horizontal_cwin));
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+
+ if (index >= (gint) cwin->nr_candidates)
+ cwin->candidate_index = 0;
+ else
+ cwin->candidate_index = index;
+
+ if (cwin->candidate_index >= 0 && cwin->display_limit)
+ new_page = cwin->candidate_index / cwin->display_limit;
+ else
+ new_page = cwin->page_index;
+
+ if (cwin->page_index != new_page)
+ uim_cand_win_gtk_set_page(cwin, new_page);
+
+ if (cwin->candidate_index >= 0) {
+ gint pos;
+ struct index_button *idxbutton, *prev_selected;
+
+ if (cwin->display_limit)
+ pos = cwin->candidate_index % cwin->display_limit;
+ else
+ pos = cwin->candidate_index;
+
+ idxbutton = g_ptr_array_index(horizontal_cwin->buttons, pos);
+ prev_selected = (gpointer)horizontal_cwin->selected;
+ if (prev_selected) {
+ gtk_button_set_relief(prev_selected->button, GTK_RELIEF_NONE);
+ }
+ gtk_button_set_relief(idxbutton->button, GTK_RELIEF_HALF);
+ horizontal_cwin->selected = idxbutton;
+
+ /* show subwin */
+ {
+ char *annotation = NULL;
+ GtkTreeModel *model = GTK_TREE_MODEL(cwin->stores->pdata[new_page]);
+ GtkTreeIter iter;
+
+ gtk_tree_model_iter_nth_child(model, &iter, NULL, pos);
+ gtk_tree_model_get(model, &iter, COLUMN_ANNOTATION, &annotation, -1);
+
+ if (annotation && *annotation) {
+ if (!cwin->sub_window.window)
+ uim_cand_win_gtk_create_sub_window(cwin);
+
gtk_text_buffer_set_text(gtk_text_view_get_buffer(GTK_TEXT_VIEW(cwin->sub_window.text_view)),
annotation, -1);
+ uim_cand_win_gtk_layout_sub_window(cwin);
+ gtk_widget_show(cwin->sub_window.window);
+ cwin->sub_window.active = TRUE;
+ } else {
+ if (cwin->sub_window.window) {
+ gtk_widget_hide(cwin->sub_window.window);
+ cwin->sub_window.active = FALSE;
+ }
+ }
+ free(annotation);
+ }
+ }
+
+ uim_cand_win_gtk_update_label(cwin);
+}
+
+static void
+scale_label(GtkButton *button, double scale)
+{
+ GtkWidget *label;
+ PangoAttrList *attrs = pango_attr_list_new();
+ PangoAttribute *attr = pango_attr_scale_new(scale);
+
+ pango_attr_list_insert(attrs, attr);
+ label = gtk_bin_get_child(GTK_BIN(button));
+ if (GTK_IS_LABEL(label))
+ gtk_label_set_attributes(GTK_LABEL(label), attrs);
+ pango_attr_list_unref(attrs);
+}
+
+static void
+clear_button(struct index_button *idxbutton,
+ gint cell_index)
+{
+ GtkButton *button;
+
+ 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, "");
+ scale_label(button, PANGO_SCALE_LARGE);
+}
+
+static void
+clear_all_buttons(GPtrArray *buttons)
+{
+ gint i;
+
+ for (i = 0; i < (gint)buttons->len; i++) {
+ struct index_button *idxbutton;
+
+ idxbutton = g_ptr_array_index(buttons, i);
+ if (idxbutton && idxbutton->cand_index_in_page != -1) {
+ clear_button(idxbutton, i);
+ }
+ }
+}
+
+static void
+update_table_button(UIMCandWinHorizontalGtk *horizontal_cwin, guint
new_page)
+{
+ UIMCandWinGtk *cwin;
+ GtkTreeModel *model;
+ GPtrArray *buttons;
+ GtkTreeIter ti;
+ gboolean has_next;
+ gint display_limit, len, cand_index = 0;
+
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+ model = GTK_TREE_MODEL(cwin->stores->pdata[new_page]);
+ buttons = horizontal_cwin->buttons;
+ display_limit = cwin->display_limit;
+ len = buttons->len;
+
+ clear_all_buttons(buttons);
+ has_next = gtk_tree_model_get_iter_first(model, &ti);
+ while (has_next) {
+ gchar *heading;
+ gchar *cand_str;
+ GtkButton *button = NULL;
+
+ gtk_tree_model_get(model, &ti, COLUMN_HEADING, &heading,
+ COLUMN_CANDIDATE, &cand_str, TERMINATOR);
+ if (cand_str != NULL) {
+ button = assign_cellbutton(horizontal_cwin, heading, cand_index,
display_limit);
+ if (button != NULL) {
+ gtk_button_set_relief(button, GTK_RELIEF_NONE);
+ gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
+ if (heading && heading[0] != '\0') {
+ gchar *label = g_strdup_printf("%s: %s", heading, cand_str);
+ gtk_button_set_label(button, label);
+ g_free(label);
+
+ } else {
+ gtk_button_set_label(button, cand_str);
+ }
+ scale_label(button, PANGO_SCALE_LARGE);
+ }
+ }
+
+ g_free(cand_str);
+ g_free(heading);
+ cand_index++;
+ has_next = gtk_tree_model_iter_next(model, &ti);
+ }
+
+ if (cand_index < len) {
+ gint i;
+ for (i = len - 1; i >= cand_index; i--) {
+ struct index_button *idxbutton;
+ idxbutton = g_ptr_array_index(buttons, i);
+ if (idxbutton == horizontal_cwin->selected)
+ horizontal_cwin->selected = NULL;
+ gtk_widget_destroy(GTK_WIDGET(idxbutton->button));
+ g_free(idxbutton);
+ g_ptr_array_remove_index(buttons, i);
+ }
+
+ gtk_table_resize(GTK_TABLE(cwin->view), 1, cand_index);
+ }
+}
+
+void
+uim_cand_win_horizontal_gtk_set_page(UIMCandWinHorizontalGtk
*horizontal_cwin, gint page)
+{
+ guint len, new_page;
+ gint new_index;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(horizontal_cwin));
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+ g_return_if_fail(cwin->stores);
+
+ len = cwin->stores->len;
+ g_return_if_fail(len);
+
+ if (page < 0)
+ new_page = len - 1;
+ else if (page >= (gint) len)
+ new_page = 0;
+ else
+ new_page = page;
+
+ update_table_button(horizontal_cwin, new_page);
+ show_table(GTK_TABLE(cwin->view), horizontal_cwin->buttons);
+
+ cwin->page_index = new_page;
+
+ if (cwin->display_limit) {
+ if (cwin->candidate_index >= 0)
+ new_index
+ = (new_page * cwin->display_limit) + (cwin->candidate_index %
cwin->display_limit);
+ else
+ new_index = -1;
+ } else {
+ new_index = cwin->candidate_index;
+ }
+
+ if (new_index >= (gint) cwin->nr_candidates)
+ new_index = cwin->nr_candidates - 1;
+
+ uim_cand_win_gtk_set_index(cwin, new_index);
+}
+
+static void
+show_table(GtkTable *view, GPtrArray *buttons)
+{
+ gint col;
+
+ for (col = 0; col < (gint)buttons->len; col++) {
+ GtkButton *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(GTK_WIDGET(view));
+}
+
+#define UIM_ANNOTATION_WIN_WIDTH 280
+#define UIM_ANNOTATION_WIN_HEIGHT 140
+
+void
+uim_cand_win_horizontal_gtk_create_sub_window(UIMCandWinHorizontalGtk
*horizontal_cwin)
+{
+ GtkWidget *window, *scrwin, *text_view, *frame;
+ GdkGeometry hints;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(horizontal_cwin));
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+
+ if (cwin->sub_window.window)
+ return;
+
+ cwin->sub_window.window = window = gtk_window_new(GTK_WINDOW_POPUP);
+
+ frame = gtk_frame_new(NULL);
+ gtk_container_set_border_width(GTK_CONTAINER(frame), 0);
+
+ hints.min_width = UIM_ANNOTATION_WIN_WIDTH;
+ hints.min_height = UIM_ANNOTATION_WIN_HEIGHT;
+ hints.max_width = UIM_ANNOTATION_WIN_WIDTH;
+ hints.max_height = UIM_ANNOTATION_WIN_HEIGHT;
+ gtk_window_set_geometry_hints(GTK_WINDOW(window), frame, &hints,
GDK_HINT_MAX_SIZE | GDK_HINT_MIN_SIZE);
+
+ cwin->sub_window.scrolled_window = scrwin =
gtk_scrolled_window_new(NULL, NULL);
+ gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrwin),
+ GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
+
+ cwin->sub_window.text_view = text_view = gtk_text_view_new();
+ gtk_text_view_set_editable(GTK_TEXT_VIEW(text_view), FALSE);
+ gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text_view),
GTK_WRAP_WORD_CHAR);
+ gtk_widget_show(text_view);
+
+ gtk_container_add(GTK_CONTAINER(scrwin), text_view);
+ gtk_container_add(GTK_CONTAINER(frame), scrwin);
+ gtk_container_add(GTK_CONTAINER(window), frame);
+ gtk_widget_show(frame);
+ gtk_widget_show(scrwin);
+ gtk_widget_show(text_view);
+}
+
+void
+uim_cand_win_horizontal_gtk_layout_sub_window(UIMCandWinHorizontalGtk
*horizontal_cwin)
+{
+ UIMCandWinGtk *cwin;
+#if GTK_CHECK_VERSION(2, 90, 0)
+ gint x, y, w, h, x2, y2, w2, h2, x3, y3;
+#else
+ gint x, y, w, h, d, x2, y2, w2, h2, d2, x3, y3;
+#endif
+ struct index_button *idxbutton;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_HORIZONTAL_GTK(horizontal_cwin));
+ cwin = UIM_CAND_WIN_GTK(horizontal_cwin);
+
+ if (!cwin->sub_window.window)
+ return;
+
+#if GTK_CHECK_VERSION(2, 90, 0)
+ gdk_window_get_geometry(gtk_widget_get_window(GTK_WIDGET(cwin)),
+ &x, &y, &w, &h);
+#else
+ gdk_window_get_geometry(gtk_widget_get_window(GTK_WIDGET(cwin)),
+ &x, &y, &w, &h, &d);
+#endif
+ gdk_window_get_origin(gtk_widget_get_window(GTK_WIDGET(cwin)), &x, &y);
+
+#if GTK_CHECK_VERSION(2, 90, 0)
+ gdk_window_get_geometry(gtk_widget_get_window(cwin->sub_window.window),
+ &x2, &y2, &w2, &h2);
+#else
+ gdk_window_get_geometry(gtk_widget_get_window(cwin->sub_window.window),
+ &x2, &y2, &w2, &h2, &d2);
+#endif
+
+ if (horizontal_cwin->selected) {
+ GtkWidget *button;
+ idxbutton = horizontal_cwin->selected;
+ button = GTK_WIDGET(idxbutton->button);
+ gdk_window_get_origin(gtk_widget_get_window(button), &x3, &y3);
+
+#if GTK_CHECK_VERSION(2, 18, 0)
+ if (!gtk_widget_get_has_window(button)) {
+ GtkAllocation allocation;
+ gtk_widget_get_allocation(button, &allocation);
+ x3 += allocation.x;
+ }
+#else
+ if (GTK_WIDGET_NO_WINDOW(button))
+ x3 += button->allocation.x;
+#endif
+ }
+ y = y + h;
+
+ gtk_window_move(GTK_WINDOW(cwin->sub_window.window), x3, y);
+}
=======================================
--- /dev/null
+++ /trunk/gtk2/immodule/uim-cand-win-horizontal-gtk.h Thu Jun 16 23:54:38
2011
@@ -0,0 +1,72 @@
+/*
+
+ Copyright (c) 2003-2011 uim Project http://code.google.com/p/uim/
+
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions
+ are met:
+
+ 1. Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ 3. Neither the name of authors nor the names of its contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
IS'' AND
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE
+ ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS
BE LIABLE
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT
+ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ SUCH DAMAGE.
+
+*/
+
+#ifndef UIM_GTK_UIM_CAND_WIN_HORIZONTAL_GTK_H
+#define UIM_GTK_UIM_CAND_WIN_HORIZONTAL_GTK_H
+
+#include "uim-cand-win-gtk.h"
+
+G_BEGIN_DECLS
+
+#define UIM_TYPE_CAND_WIN_HORIZONTAL_GTK
(uim_cand_win_horizontal_gtk_get_type ())
+#define UIM_CAND_WIN_HORIZONTAL_GTK(obj)
(G_TYPE_CHECK_INSTANCE_CAST((obj), UIM_TYPE_CAND_WIN_HORIZONTAL_GTK,
UIMCandWinHorizontalGtk))
+#define UIM_CAND_WIN_HORIZONTAL_GTK_CLASS(klass)
(G_TYPE_CHECK_CLASS_CAST((klass), UIM_TYPE_CAND_WIN_HORIZONTAL_GTK,
UIMCandWinHorizontalGtkClass))
+#define UIM_IS_CAND_WIN_HORIZONTAL_GTK(obj)
(G_TYPE_CHECK_INSTANCE_TYPE((obj), UIM_TYPE_CAND_WIN_HORIZONTAL_GTK))
+#define UIM_IS_CAND_WIN_HORIZONTAL_GTK_CLASS(klass)
(G_TYPE_CHECK_CLASS_TYPE ((klass), UIM_TYPE_CAND_WIN_HORIZONTAL_GTK))
+#define UIM_CAND_WIN_HORIZONTAL_GTK_GET_CLASS(obj)
(G_TYPE_INSTANCE_GET_CLASS ((obj), UIM_TYPE_CAND_WIN_HORIZONTAL_GTK,
UIMCandWinHorizontalGtkClass))
+
+typedef struct _UIMCandWinHorizontalGtk UIMCandWinHorizontalGtk;
+typedef struct _UIMCandWinHorizontalGtkClass UIMCandWinHorizontalGtkClass;
+
+struct _UIMCandWinHorizontalGtk {
+ UIMCandWinGtk parent;
+ GPtrArray *buttons;
+ gpointer selected;
+};
+
+struct _UIMCandWinHorizontalGtkClass {
+ UIMCandWinGtkClass parent_class;
+};
+
+GType uim_cand_win_horizontal_gtk_register_type(GTypeModule *module);
+GType uim_cand_win_horizontal_gtk_get_type(void);
+UIMCandWinHorizontalGtk *uim_cand_win_horizontal_gtk_new(void);
+
+void uim_cand_win_horizontal_gtk_set_index(UIMCandWinHorizontalGtk *cwin,
gint index);
+void uim_cand_win_horizontal_gtk_set_page(UIMCandWinHorizontalGtk *cwin,
gint page);
+void uim_cand_win_horizontal_gtk_create_sub_window(UIMCandWinHorizontalGtk
*cwin);
+void uim_cand_win_horizontal_gtk_layout_sub_window(UIMCandWinHorizontalGtk
*cwin);
+
+G_END_DECLS
+
+#endif /*UIM_GTK_UIM_CAND_WIN_HORIZONTAL_GTK_H */
=======================================
--- /trunk/gtk2/immodule/Makefile.am Thu Jun 16 00:09:29 2011
+++ /trunk/gtk2/immodule/Makefile.am Thu Jun 16 23:54:38 2011
@@ -24,6 +24,7 @@
gtk-im-uim.c gtk-im-uim.h key-util-gtk.c key-util-gtk.h \
uim-cand-win-gtk.c uim-cand-win-gtk.h \
uim-cand-win-tbl-gtk.c uim-cand-win-tbl-gtk.h \
+ uim-cand-win-horizontal-gtk.c uim-cand-win-horizontal-gtk.h \
caret-state-indicator.c caret-state-indicator.h \
compose.c compose.h text-util.c text-util.h
=======================================
--- /trunk/gtk2/immodule/gtk-im-uim.c Tue May 24 07:44:08 2011
+++ /trunk/gtk2/immodule/gtk-im-uim.c Thu Jun 16 23:54:38 2011
@@ -60,6 +60,7 @@
#include "gtk-im-uim.h"
#include "uim-cand-win-gtk.h"
#include "uim-cand-win-tbl-gtk.h"
+#include "uim-cand-win-horizontal-gtk.h"
#include "caret-state-indicator.h"
#include "key-util-gtk.h"
#ifdef GDK_WINDOWING_X11
@@ -1416,14 +1417,21 @@
static UIMCandWinGtk *
im_uim_create_cand_win_gtk()
{
- UIMCandWinGtk *cwin;
+ UIMCandWinGtk *cwin = NULL;
char *candwinprog = uim_scm_symbol_value_str("uim-candwin-prog");
- if (candwinprog && !strncmp(candwinprog, "uim-candwin-tbl", 15)) {
- cwin = UIM_CAND_WIN_GTK(uim_cand_win_tbl_gtk_new());
- } else {
- cwin = uim_cand_win_gtk_new();
- }
+
+ if (candwinprog) {
+ if (!strncmp(candwinprog, "uim-candwin-tbl", 15))
+ cwin = UIM_CAND_WIN_GTK(uim_cand_win_tbl_gtk_new());
+ else if (!strncmp(candwinprog, "uim-candwin-horizontal", 22))
+ cwin = UIM_CAND_WIN_GTK(uim_cand_win_horizontal_gtk_new());
+ }
+
+ if (!cwin)
+ cwin = uim_cand_win_gtk_new();
+
free(candwinprog);
+
return cwin;
}
=======================================
--- /trunk/gtk2/immodule/uim-cand-win-gtk.c Tue May 24 07:44:08 2011
+++ /trunk/gtk2/immodule/uim-cand-win-gtk.c Thu Jun 16 23:54:38 2011
@@ -60,12 +60,12 @@
static void uim_cand_win_gtk_dispose (GObject *obj);
static void uim_cand_win_gtk_map (GtkWidget *widget);
static void uim_cand_win_gtk_unmap (GtkWidget *widget);
-static void uim_cand_win_gtk_create_sub_window(UIMCandWinGtk *cwin);
-static void uim_cand_win_gtk_layout_sub_window(UIMCandWinGtk *cwin);
static void uim_cand_win_gtk_real_set_index (UIMCandWinGtk *cwin,
gint index);
static void uim_cand_win_gtk_real_set_page (UIMCandWinGtk *cwin,
gint page);
+static void uim_cand_win_gtk_real_create_sub_window(UIMCandWinGtk *cwin);
+static void uim_cand_win_gtk_real_layout_sub_window (UIMCandWinGtk *cwin);
static gboolean tree_selection_change (GtkTreeSelection
*selection,
GtkTreeModel *model,
@@ -138,6 +138,8 @@
klass->set_index = uim_cand_win_gtk_real_set_index;
klass->set_page = uim_cand_win_gtk_real_set_page;
+ klass->create_sub_window = uim_cand_win_gtk_real_create_sub_window;
+ klass->layout_sub_window = uim_cand_win_gtk_real_layout_sub_window;
}
void
@@ -846,7 +848,8 @@
cursor_y = cwin->cursor.y;
if (sc_wi < topwin_x + cursor_x + cw_wi) {
- x = topwin_x + cursor_x - cw_wi;
+ /* x = topwin_x + cursor_x - cw_wi; */
+ x = sc_wi - cw_wi;
} else {
x = topwin_x + cursor_x;
}
@@ -870,12 +873,18 @@
cwin->cursor = *area;
}
+
+void
+uim_cand_win_gtk_create_sub_window(UIMCandWinGtk *cwin)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->create_sub_window(cwin);
+}
#define UIM_ANNOTATION_WIN_WIDTH 200
#define UIM_ANNOTATION_WIN_HEIGHT 200
-static void
-uim_cand_win_gtk_create_sub_window(UIMCandWinGtk *cwin)
+void
+uim_cand_win_gtk_real_create_sub_window(UIMCandWinGtk *cwin)
{
GtkWidget *window, *scrwin, *text_view, *frame;
GdkGeometry hints;
@@ -911,8 +920,15 @@
gtk_widget_show(text_view);
}
-static void
+
+void
uim_cand_win_gtk_layout_sub_window(UIMCandWinGtk *cwin)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->layout_sub_window(cwin);
+}
+
+void
+uim_cand_win_gtk_real_layout_sub_window(UIMCandWinGtk *cwin)
{
#if GTK_CHECK_VERSION(2, 90, 0)
gint x, y, w, h, sw, sh, x2, y2, w2, h2;
=======================================
--- /trunk/gtk2/immodule/uim-cand-win-gtk.h Tue May 24 07:44:08 2011
+++ /trunk/gtk2/immodule/uim-cand-win-gtk.h Thu Jun 16 23:54:38 2011
@@ -90,6 +90,8 @@
/* member functions */
void (*set_index) (UIMCandWinGtk *cwin, gint index);
void (*set_page) (UIMCandWinGtk *cwin, gint page);
+ void (*create_sub_window) (UIMCandWinGtk *cwin);
+ void (*layout_sub_window) (UIMCandWinGtk *cwin);
};
@@ -139,6 +141,9 @@
void uim_cand_win_gtk_update_label (UIMCandWinGtk *cwin);
+void uim_cand_win_gtk_create_sub_window(UIMCandWinGtk *cwin);
+void uim_cand_win_gtk_layout_sub_window(UIMCandWinGtk *cwin);
+
G_END_DECLS
#endif /*UIM_GTK_UIM_CAND_WIN_GTK_H */
=======================================
--- /trunk/gtk3/immodule/Makefile.am Tue May 24 07:44:08 2011
+++ /trunk/gtk3/immodule/Makefile.am Thu Jun 16 23:54:38 2011
@@ -27,6 +27,8 @@
../../gtk2/immodule/uim-cand-win-gtk.h \
../../gtk2/immodule/uim-cand-win-tbl-gtk.c \
../../gtk2/immodule/uim-cand-win-tbl-gtk.h \
+ ../../gtk2/immodule/uim-cand-win-horizontal-gtk.c \
+ ../../gtk2/immodule/uim-cand-win-horizontal-gtk.h \
../../gtk2/immodule/caret-state-indicator.c \
../../gtk2/immodule/caret-state-indicator.h \
../../gtk2/immodule/compose.c ../../gtk2/immodule/compose.h \