Revision: 6442
Author: deton.kih
Date: Sun Jun 13 00:30:03 2010
Log: * Add new table style candidate window for GTK+ immodule [uim-ja 234]
* gtk/uim-cand-win-tbl-gtk.c
- New file. Add UIMCandWinTblGtk which inherits from UIMCandWinGtk
* gtk/uim-cand-win-tbl-gtk.h
- New file
* gtk/gtk-im-uim.c
- (im_uim_create_cand_win_gtk): New function
* gtk/uim-cand-win-gtk.h
- (_UIMCandWinGtkClass): Add member functions
to override in UIMCandWinTblGtkClass
* gtk/uim-cand-win-gtk.c
- (set_candidates, set_page_candidates, set_index, set_page):
Change to virtual member functions to override in UIMCandWinTblGtk
- (uim_cand_win_gtk_update_label): Rename from update_label
to use in uim-cand-win-tbl-gtk.c
* gtk/Makefile.am
- (IM_UIM_SOURCES): Add uim-cand-win-tbl-gtk.c uim-cand-win-tbl-gtk.h
http://code.google.com/p/uim/source/detail?r=6442
Added:
/trunk/gtk/uim-cand-win-tbl-gtk.c
/trunk/gtk/uim-cand-win-tbl-gtk.h
Modified:
/trunk/gtk/Makefile.am
/trunk/gtk/gtk-im-uim.c
/trunk/gtk/uim-cand-win-gtk.c
/trunk/gtk/uim-cand-win-gtk.h
=======================================
--- /dev/null
+++ /trunk/gtk/uim-cand-win-tbl-gtk.c Sun Jun 13 00:30:03 2010
@@ -0,0 +1,639 @@
+/*
+
+ copyright (c) 2003-2010 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-tbl-gtk.h"
+#include <string.h>
+#include <stdlib.h>
+#include <uim/uim.h>
+#include <uim/uim-scm.h>
+
+#define DEFAULT_MIN_WINDOW_WIDTH 80
+
+enum {
+ TERMINATOR = -1,
+ COLUMN_HEADING,
+ COLUMN_CANDIDATE1,
+ COLUMN_CANDIDATE2,
+ COLUMN_CANDIDATE3,
+ COLUMN_CANDIDATE4,
+ COLUMN_CANDIDATE5,
+ COLUMN_CANDIDATE6,
+ COLUMN_CANDIDATE7,
+ COLUMN_CANDIDATE8,
+ COLUMN_CANDIDATE9,
+ COLUMN_CANDIDATE10,
+ COLUMN_CANDIDATE11,
+ COLUMN_CANDIDATE12,
+ COLUMN_CANDIDATE13,
+ NR_COLUMNS
+};
+
+#define LABELCHAR_NR_COLUMNS 13
+#define LABELCHAR_NR_ROWS 8
+#define LABELCHAR_NR_CELLS (LABELCHAR_NR_COLUMNS * LABELCHAR_NR_ROWS)
+#define INDEX(row,col) ((row) * LABELCHAR_NR_COLUMNS + (col))
+/* 106 keyboard */
+static gchar default_labelchar_table[LABELCHAR_NR_CELLS] = {
+ '1','2','3','4','5', '6','7','8','9','0', '-','^','\\',
+ 'q','w','e','r','t', 'y','u','i','o','p', '@','[','\0',
+ 'a','s','d','f','g', 'h','j','k','l',';', ':',']','\0',
+ 'z','x','c','v','b', 'n','m',',','.','/', '\0','\0',' ',
+ '!','"','#','$','%', '&','\'','(',')','\0', '=','~','|',
+ 'Q','W','E','R','T', 'Y','U','I','O','P', '`','{','\0',
+ 'A','S','D','F','G', 'H','J','K','L','+', '*','}','\0',
+ 'Z','X','C','V','B', 'N','M','<','>','?', '_','\0','\0',
+};
+/* labelchar_table consists of four blocks
+ * blockLR blockA
+ * blockLRS blockAS
+ */
+#define BLOCK_A_ROW_START 0
+#define BLOCK_A_ROW_END 4
+#define BLOCK_A_COLUMN_START 10
+#define BLOCK_A_COLUMN_END LABELCHAR_NR_COLUMNS
+#define BLOCK_LRS_ROW_START BLOCK_A_ROW_END
+#define BLOCK_LRS_ROW_END LABELCHAR_NR_ROWS
+#define BLOCK_LRS_COLUMN_START 0
+#define BLOCK_LRS_COLUMN_END BLOCK_A_COLUMN_START
+#define BLOCK_AS_ROW_START BLOCK_LRS_ROW_START
+#define BLOCK_AS_ROW_END BLOCK_LRS_ROW_END
+#define BLOCK_AS_COLUMN_START BLOCK_LRS_COLUMN_END
+#define BLOCK_AS_COLUMN_END LABELCHAR_NR_COLUMNS
+
+#define BLOCK_SPACING 20
+#define HOMEPOSITION_SPACING 2
+#define SPACING_LEFT_BLOCK_COLUMN 4
+#define SPACING_RIGHT_BLOCK_COLUMN (BLOCK_A_COLUMN_START - 1)
+#define SPACING_UP_BLOCK_ROW (BLOCK_A_ROW_END - 1)
+#define SPACING_LEFTHAND_FAR_COLUMN 3
+#define SPACING_RIGHTHAND_FAR_COLUMN 5
+#define SPACING_UPPER_FAR_ROW 0
+#define SPACING_SHIFT_UPPER_FAR_ROW 4
+
+static void uim_cand_win_tbl_gtk_init (UIMCandWinTblGtk
*cwin);
+static void uim_cand_win_tbl_gtk_class_init (UIMCandWinGtkClass *klass);
+static void uim_cand_win_tbl_gtk_dispose (GObject *obj);
+static gchar *init_labelchar_table(void);
+static void show_table(GtkTable *view, GPtrArray *buttons);
+
+
+static GType cand_win_tbl_type = 0;
+static GTypeInfo const object_info = {
+ sizeof (UIMCandWinTblGtkClass),
+ (GBaseInitFunc) NULL,
+ (GBaseFinalizeFunc) NULL,
+ (GClassInitFunc) uim_cand_win_tbl_gtk_class_init,
+ (GClassFinalizeFunc) NULL,
+ NULL, /* class_data */
+ sizeof (UIMCandWinTblGtk),
+ 0, /* n_preallocs */
+ (GInstanceInitFunc) uim_cand_win_tbl_gtk_init,
+};
+
+static GtkWindowClass *parent_class = NULL;
+
+GType
+uim_cand_win_tbl_gtk_get_type(void)
+{
+ if (!cand_win_tbl_type)
+ cand_win_tbl_type =
g_type_register_static(UIM_TYPE_CAND_WIN_GTK, "UIMCandWinTblGtk",
+ &object_info, (GTypeFlags)0);
+ return cand_win_tbl_type;
+}
+
+GType
+uim_cand_win_tbl_gtk_register_type(GTypeModule *module)
+{
+ if (!cand_win_tbl_type)
+ cand_win_tbl_type = g_type_module_register_type(module,
+ UIM_TYPE_CAND_WIN_GTK,
+ "UIMCandWinTblGtk",
+ &object_info, 0);
+ return cand_win_tbl_type;
+}
+
+static void
+uim_cand_win_tbl_gtk_class_init (UIMCandWinGtkClass *klass)
+{
+ GObjectClass *object_class = (GObjectClass *) klass;
+
+ parent_class = g_type_class_peek_parent (klass);
+ object_class->dispose = uim_cand_win_tbl_gtk_dispose;
+
+ klass->set_candidates = (void (*)(UIMCandWinGtk *, guint, GSList
*))uim_cand_win_tbl_gtk_set_candidates;
+ klass->set_page_candidates = (void (*)(UIMCandWinGtk *, guint, GSList
*))uim_cand_win_tbl_gtk_set_page_candidates;
+ klass->set_index = (void (*)(UIMCandWinGtk *,
gint))uim_cand_win_tbl_gtk_set_index;
+ klass->set_page = (void (*)(UIMCandWinGtk *,
gint))uim_cand_win_tbl_gtk_set_page;
+}
+
+static void
+uim_cand_win_tbl_gtk_init (UIMCandWinTblGtk *ctblwin)
+{
+ gint row, col;
+ GtkWidget *viewport;
+ UIMCandWinGtk *cwin;
+ cwin = UIM_CAND_WIN_GTK(ctblwin);
+
+ ctblwin->buttons = g_ptr_array_new();
+ ctblwin->labelchar_table = init_labelchar_table();
+
+ gtk_widget_destroy(cwin->view);
+ cwin->view = gtk_table_new(LABELCHAR_NR_ROWS, LABELCHAR_NR_COLUMNS,
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 (row = 0; row < LABELCHAR_NR_ROWS; row++) {
+ for (col = 0; col < LABELCHAR_NR_COLUMNS; col++) {
+ GtkWidget *button;
+ button = gtk_button_new_with_label(" ");
+ gtk_table_attach_defaults(GTK_TABLE(cwin->view), button,
+ col, col + 1, row, row + 1);
+ g_ptr_array_add(ctblwin->buttons, button);
+ }
+ }
+ gtk_table_set_col_spacing(GTK_TABLE(cwin->view),
SPACING_LEFT_BLOCK_COLUMN,
+ BLOCK_SPACING);
+ gtk_table_set_col_spacing(GTK_TABLE(cwin->view),
SPACING_RIGHT_BLOCK_COLUMN,
+ BLOCK_SPACING);
+ gtk_table_set_row_spacing(GTK_TABLE(cwin->view), SPACING_UP_BLOCK_ROW,
+ BLOCK_SPACING);
+ gtk_table_set_col_spacing(GTK_TABLE(cwin->view),
SPACING_LEFTHAND_FAR_COLUMN,
+ HOMEPOSITION_SPACING);
+ gtk_table_set_col_spacing(GTK_TABLE(cwin->view),
SPACING_RIGHTHAND_FAR_COLUMN,
+ HOMEPOSITION_SPACING);
+ gtk_table_set_row_spacing(GTK_TABLE(cwin->view), SPACING_UPPER_FAR_ROW,
+ HOMEPOSITION_SPACING);
+ gtk_table_set_row_spacing(GTK_TABLE(cwin->view),
SPACING_SHIFT_UPPER_FAR_ROW,
+ HOMEPOSITION_SPACING);
+
+ 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 gchar *
+init_labelchar_table(void)
+{
+ gchar *table;
+ uim_lisp list;
+ size_t len = 0;
+ uim_lisp *ary0, *ary;
+ guint i;
+
+ list = uim_scm_symbol_value("uim-candwin-prog-layout");
+ if (list == NULL || !uim_scm_listp(list)) {
+ return default_labelchar_table;
+ }
+ ary0 = ary = (uim_lisp *)uim_scm_list2array(list, &len, NULL);
+ if (ary == NULL || len <= 0) {
+ if (ary0) {
+ free(ary0);
+ }
+ return default_labelchar_table;
+ }
+ table = (gchar *)g_malloc(LABELCHAR_NR_CELLS);
+ if (table == NULL) {
+ free(ary0);
+ return default_labelchar_table;
+ }
+ for (i = 0; i < LABELCHAR_NR_CELLS; i++, ary++) {
+ table[i] = '\0';
+ if (i < len) {
+ char *str = uim_scm_c_str(*ary);
+ if (str) {
+ table[i] = *str;
+ free(str);
+ }
+ }
+ }
+ free(ary0);
+ return table;
+}
+
+static void
+uim_cand_win_tbl_gtk_dispose (GObject *obj)
+{
+ UIMCandWinTblGtk *ctblwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_TBL_GTK(obj));
+
+ ctblwin = UIM_CAND_WIN_TBL_GTK(obj);
+
+ if (ctblwin->labelchar_table != default_labelchar_table) {
+ g_free(ctblwin->labelchar_table);
+ ctblwin->labelchar_table = NULL;
+ }
+ if (ctblwin->buttons) {
+ g_ptr_array_free(ctblwin->buttons, TRUE);
+ ctblwin->buttons = NULL;
+ }
+
+ if (G_OBJECT_CLASS (parent_class)->dispose)
+ G_OBJECT_CLASS (parent_class)->dispose(obj);
+}
+
+UIMCandWinTblGtk *
+uim_cand_win_tbl_gtk_new (void)
+{
+ GObject *obj = g_object_new(UIM_TYPE_CAND_WIN_TBL_GTK,
+ "type", GTK_WINDOW_POPUP,
+ NULL);
+ return UIM_CAND_WIN_TBL_GTK(obj);
+}
+
+static void
+get_row_column(gchar *labelchar_table, const gchar labelchar, gint *row,
gint *col)
+{
+ gint i;
+ for (i = 0; i < LABELCHAR_NR_CELLS; i++) {
+ if (labelchar_table[i] == labelchar) {
+ *row = i / LABELCHAR_NR_COLUMNS;
+ *col = i % LABELCHAR_NR_COLUMNS;
+ return;
+ }
+ }
+ *row = 0;
+ *col = 0;
+}
+
+static void
+set_candidate(UIMCandWinTblGtk *ctblwin, GSList *node, GtkListStore *store)
+{
+ if (node) {
+ GtkTreeIter ti;
+ gint row = 0;
+ gint col = 0;
+ gint i;
+ const char *heading_label = NULL;
+ const char *cand_str = NULL;
+ uim_candidate cand = node->data;
+
+ heading_label = uim_candidate_get_heading_label(cand);
+ cand_str = uim_candidate_get_cand_str(cand);
+
+ get_row_column(ctblwin->labelchar_table, heading_label[0], &row, &col);
+ gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &ti);
+ for (i = 0; i < row; i++) {
+ gtk_tree_model_iter_next(GTK_TREE_MODEL(store), &ti);
+ }
+ gtk_list_store_set(store, &ti, col, cand_str, TERMINATOR);
+ } else {
+ /* No need to set any data for empty row. */
+ }
+}
+
+void
+uim_cand_win_tbl_gtk_set_candidates(UIMCandWinTblGtk *ctblwin,
+ guint display_limit,
+ GSList *candidates)
+{
+ gint i, nr_stores = 1;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_TBL_GTK(ctblwin));
+ cwin = UIM_CAND_WIN_GTK(ctblwin);
+
+ if (cwin->stores == NULL)
+ cwin->stores = g_ptr_array_new();
+
+ /* remove old data */
+ if (cwin->page_index >= 0 && cwin->page_index < (int) cwin->stores->len)
{
+ /* Remove data from current page to shrink the window */
+ if (cwin->stores->pdata[cwin->page_index])
+ gtk_list_store_clear(cwin->stores->pdata[cwin->page_index]);
+ }
+ for (i = cwin->stores->len - 1; i >= 0; i--) {
+ GtkListStore *store = g_ptr_array_remove_index(cwin->stores, i);
+ if (store)
+ g_object_unref(G_OBJECT(store));
+ }
+
+ cwin->candidate_index = -1;
+ cwin->nr_candidates = g_slist_length(candidates);
+ cwin->display_limit = display_limit;
+
+ cwin->sub_window.active = FALSE;
+
+ if (candidates == NULL)
+ return;
+
+ /* calculate number of GtkListStores to create */
+ if (display_limit) {
+ nr_stores = cwin->nr_candidates / display_limit;
+ if (cwin->nr_candidates > display_limit * nr_stores)
+ nr_stores++;
+ }
+
+ /* create GtkListStores, and set candidates */
+ for (i = 0; i < nr_stores; i++) {
+ GtkListStore *store = gtk_list_store_new(LABELCHAR_NR_COLUMNS,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING);
+ GSList *node;
+ guint j;
+
+ g_ptr_array_add(cwin->stores, store);
+
+ for (j = 0; j < LABELCHAR_NR_ROWS; j++) {
+ GtkTreeIter ti;
+ gtk_list_store_append(store, &ti);
+ }
+
+ /* set candidates */
+ for (j = i * display_limit, node = g_slist_nth(candidates, j);
+ display_limit ? j < display_limit * (i + 1) : j < cwin->nr_candidates;
+ j++, node = g_slist_next(node))
+ {
+ set_candidate(ctblwin, node, store);
+ }
+ }
+
+ uim_cand_win_gtk_set_page(cwin, 0);
+
+ uim_cand_win_gtk_update_label(cwin);
+}
+
+void
+uim_cand_win_tbl_gtk_set_page_candidates(UIMCandWinTblGtk *ctblwin,
+ guint page,
+ GSList *candidates)
+{
+ GtkListStore *store;
+ GSList *node;
+ gint j, len;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_TBL_GTK(ctblwin));
+ cwin = UIM_CAND_WIN_GTK(ctblwin);
+
+ if (candidates == NULL)
+ return;
+
+ cwin->sub_window.active = FALSE;
+ len = g_slist_length(candidates);
+
+ /* create GtkListStores, and set candidates */
+ store = gtk_list_store_new(LABELCHAR_NR_COLUMNS, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING,
+ G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
+
+ cwin->stores->pdata[page] = store;
+
+ for (j = 0; j < LABELCHAR_NR_ROWS; j++) {
+ GtkTreeIter ti;
+ gtk_list_store_append(store, &ti);
+ }
+
+ /* set candidates */
+ for (j = 0, node = g_slist_nth(candidates, j);
+ j < len;
+ j++, node = g_slist_next(node))
+ {
+ set_candidate(ctblwin, node, store);
+ }
+}
+
+void
+uim_cand_win_tbl_gtk_set_index(UIMCandWinTblGtk *ctblwin, gint index)
+{
+ gint new_page;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_TBL_GTK(ctblwin));
+ cwin = UIM_CAND_WIN_GTK(ctblwin);
+
+ 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);
+
+ uim_cand_win_gtk_update_label(cwin);
+}
+
+static void
+update_table_button(GtkTreeModel *model, GPtrArray *buttons, gchar
*labelchar_table)
+{
+ GtkTreeIter ti;
+ gint row, col;
+ gboolean hasValue = TRUE;
+ gtk_tree_model_get_iter_first(model, &ti);
+ for (row = 0; row < LABELCHAR_NR_ROWS; row++) {
+ for (col = 0; col < LABELCHAR_NR_COLUMNS; col++) {
+ GValue value = {0};
+ const gchar *str = NULL;
+ GtkButton *button;
+ button = g_ptr_array_index(buttons, INDEX(row, col));
+ if (hasValue) {
+ gtk_tree_model_get_value(model, &ti, col, &value);
+ str = g_value_get_string(&value);
+ }
+ if (str == NULL) {
+ str = " ";
+ if (labelchar_table[INDEX(row, col)] == '\0') {
+ gtk_button_set_relief(button, GTK_RELIEF_NONE);
+ } else {
+ gtk_button_set_relief(button, GTK_RELIEF_HALF);
+ }
+ gtk_widget_set_sensitive(GTK_WIDGET(button), FALSE);
+ } else {
+ gtk_button_set_relief(button, GTK_RELIEF_NORMAL);
+ gtk_widget_set_sensitive(GTK_WIDGET(button), TRUE);
+ }
+ gtk_button_set_label(button, str);
+ if (hasValue) {
+ g_value_unset(&value);
+ }
+ }
+ if (hasValue) {
+ hasValue = gtk_tree_model_iter_next(model, &ti);
+ }
+ }
+}
+
+void
+uim_cand_win_tbl_gtk_set_page(UIMCandWinTblGtk *ctblwin, gint page)
+{
+ guint len, new_page;
+ gint new_index;
+ UIMCandWinGtk *cwin;
+
+ g_return_if_fail(UIM_IS_CAND_WIN_TBL_GTK(ctblwin));
+ cwin = UIM_CAND_WIN_GTK(ctblwin);
+ 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(GTK_TREE_MODEL(cwin->stores->pdata[new_page]),
+ ctblwin->buttons, ctblwin->labelchar_table);
+ show_table(GTK_TABLE(cwin->view), ctblwin->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 gboolean
+is_empty_block(GPtrArray *buttons, gint rowstart, gint rowend, gint
colstart, gint colend)
+{
+ gint row, col;
+ for (row = rowstart; row < rowend; row++) {
+ for (col = colstart; col < colend; col++) {
+ GtkButton *button;
+ GtkReliefStyle relief;
+ button = g_ptr_array_index(buttons, INDEX(row, col));
+ relief = gtk_button_get_relief(button);
+ if (relief == GTK_RELIEF_NORMAL) {
+ return FALSE;
+ }
+ }
+ }
+ return TRUE;
+}
+
+static void
+show_table(GtkTable *view, GPtrArray *buttons)
+{
+ /* hide empty blocks.
+ * pattern0(full table)
+ * blockLR blockA
+ * blockLRS blockAS (for shift key)
+ * pattern1(minimal blocks)
+ * blockLR
+ * pattern2(without shift blocks)
+ * blockLR blockA
+ * pattern3(without symbol blocks)
+ * blockLR
+ * blockLRS
+ */
+ gint row, col;
+ gint hide_row, hide_col;
+ gint row_spacing, col_spacing;
+ gboolean blockA, blockAS, blockLRS;
+ blockA = !is_empty_block(buttons, BLOCK_A_ROW_START, BLOCK_A_ROW_END,
+ BLOCK_A_COLUMN_START, BLOCK_A_COLUMN_END);
+ blockAS = !is_empty_block(buttons, BLOCK_AS_ROW_START, BLOCK_AS_ROW_END,
+ BLOCK_AS_COLUMN_START, BLOCK_AS_COLUMN_END);
+ blockLRS = !is_empty_block(buttons, BLOCK_LRS_ROW_START,
BLOCK_LRS_ROW_END,
+ BLOCK_LRS_COLUMN_START, BLOCK_LRS_COLUMN_END);
+
+ hide_row = LABELCHAR_NR_ROWS;
+ hide_col = LABELCHAR_NR_COLUMNS;
+ if (blockAS) { /* pattern0(full table) */
+ hide_row = LABELCHAR_NR_ROWS;
+ hide_col = LABELCHAR_NR_COLUMNS;
+ } else if (blockLRS) {
+ if (blockA) { /* pattern0(full table) */
+ hide_row = LABELCHAR_NR_ROWS;
+ hide_col = LABELCHAR_NR_COLUMNS;
+ } else { /* pattern3(without symbol blocks) */
+ hide_row = LABELCHAR_NR_ROWS;
+ hide_col = BLOCK_A_COLUMN_START;
+ }
+ } else if (blockA) { /* pattern2(without shift blocks) */
+ hide_row = BLOCK_A_ROW_END;
+ hide_col = LABELCHAR_NR_COLUMNS;
+ } else { /* pattern1(minimal blocks) */
+ hide_row = BLOCK_A_ROW_END;
+ hide_col = BLOCK_A_COLUMN_START;
+ }
+
+ for (row = 0; row < LABELCHAR_NR_ROWS; row++) {
+ for (col = 0; col < LABELCHAR_NR_COLUMNS; col++) {
+ GtkButton *button;
+ button = g_ptr_array_index(buttons, INDEX(row, col));
+ if (row >= hide_row || col >= hide_col) {
+ gtk_widget_hide(GTK_WIDGET(button));
+ } else {
+ gtk_widget_show(GTK_WIDGET(button));
+ }
+ }
+ }
+ if (hide_col <= BLOCK_A_COLUMN_START) {
+ col_spacing = 0;
+ } else {
+ col_spacing = BLOCK_SPACING;
+ }
+ if (hide_row <= BLOCK_LRS_ROW_START) {
+ row_spacing = 0;
+ } else {
+ row_spacing = BLOCK_SPACING;
+ }
+ gtk_table_set_col_spacing(view, SPACING_RIGHT_BLOCK_COLUMN, col_spacing);
+ gtk_table_set_row_spacing(view, SPACING_UP_BLOCK_ROW, row_spacing);
+ if (row_spacing) {
+ gtk_table_set_row_spacing(view, SPACING_SHIFT_UPPER_FAR_ROW,
+ HOMEPOSITION_SPACING);
+ } else {
+ gtk_table_set_row_spacing(view, SPACING_SHIFT_UPPER_FAR_ROW, 0);
+ }
+ /* gtk_table_resize(view, hide_row, hide_col); */
+ gtk_widget_show(GTK_WIDGET(view));
+}
=======================================
--- /dev/null
+++ /trunk/gtk/uim-cand-win-tbl-gtk.h Sun Jun 13 00:30:03 2010
@@ -0,0 +1,75 @@
+/*
+
+ Copyright (c) 2003-2010 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_TBL_GTK_H
+#define UIM_GTK_UIM_CAND_WIN_TBL_GTK_H
+
+#include "uim-cand-win-gtk.h"
+
+G_BEGIN_DECLS
+
+#define UIM_TYPE_CAND_WIN_TBL_GTK (uim_cand_win_tbl_gtk_get_type ())
+#define UIM_CAND_WIN_TBL_GTK(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj),
UIM_TYPE_CAND_WIN_TBL_GTK, UIMCandWinTblGtk))
+#define UIM_CAND_WIN_TBL_GTK_CLASS(klass)
(G_TYPE_CHECK_CLASS_CAST((klass), UIM_TYPE_CAND_WIN_TBL_GTK,
UIMCandWinTblGtkClass))
+#define UIM_IS_CAND_WIN_TBL_GTK(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj),
UIM_TYPE_CAND_WIN_TBL_GTK))
+#define UIM_IS_CAND_WIN_TBL_GTK_CLASS(klass)
(G_TYPE_CHECK_CLASS_TYPE((klass), UIM_TYPE_CAND_WIN_TBL_GTK))
+#define UIM_CAND_WIN_TBL_GTK_GET_CLASS(obj)
(G_TYPE_INSTANCE_GET_CLASS((obj), UIM_TYPE_CAND_WIN_TBL_GTK,
UIMCandWinTblGtkClass))
+
+typedef struct _UIMCandWinTblGtk UIMCandWinTblGtk;
+typedef struct _UIMCandWinTblGtkClass UIMCandWinTblGtkClass;
+
+struct _UIMCandWinTblGtk {
+ UIMCandWinGtk parent;
+ GPtrArray *buttons;
+ gchar *labelchar_table;
+};
+
+struct _UIMCandWinTblGtkClass {
+ UIMCandWinGtkClass parent_class;
+};
+
+
+GType uim_cand_win_tbl_gtk_register_type(GTypeModule *module);
+GType uim_cand_win_tbl_gtk_get_type(void);
+UIMCandWinTblGtk *uim_cand_win_tbl_gtk_new(void);
+
+void uim_cand_win_tbl_gtk_set_candidates(UIMCandWinTblGtk *cwin,
+ guint disp_limit, GSList *candidates);
+void uim_cand_win_tbl_gtk_set_page_candidates(UIMCandWinTblGtk *cwin,
+ guint page, GSList *candidates);
+void uim_cand_win_tbl_gtk_set_index(UIMCandWinTblGtk *cwin, gint index);
+void uim_cand_win_tbl_gtk_set_page(UIMCandWinTblGtk *cwin, gint page);
+
+G_END_DECLS
+
+#endif /* UIM_GTK_UIM_CAND_WIN_TBL_GTK_H */
=======================================
--- /trunk/gtk/Makefile.am Mon Apr 26 18:53:41 2010
+++ /trunk/gtk/Makefile.am Sun Jun 13 00:30:03 2010
@@ -24,6 +24,7 @@
IM_UIM_SOURCES = \
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 \
caret-state-indicator.c caret-state-indicator.h \
compose.c compose.h text-util.c text-util.h
=======================================
--- /trunk/gtk/gtk-im-uim.c Sun Apr 4 20:35:54 2010
+++ /trunk/gtk/gtk-im-uim.c Sun Jun 13 00:30:03 2010
@@ -59,6 +59,7 @@
#include "gtk-im-uim.h"
#include "uim-cand-win-gtk.h"
+#include "uim-cand-win-tbl-gtk.h"
#include "caret-state-indicator.h"
#include "key-util-gtk.h"
#ifdef GDK_WINDOWING_X11
@@ -1379,6 +1380,22 @@
}
update_client_widget(uic);
}
+
+static UIMCandWinGtk *
+im_uim_create_cand_win_gtk()
+{
+ UIMCandWinGtk *cwin;
+ 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) {
+ free(candwinprog);
+ }
+ return cwin;
+}
static void
im_uim_init(IMUIMContext *uic)
@@ -1393,7 +1410,7 @@
uic->nr_psegs = 0;
uic->prev_preedit_len = 0;
- uic->cwin = uim_cand_win_gtk_new();
+ uic->cwin = im_uim_create_cand_win_gtk();
#if IM_UIM_USE_TOPLEVEL
cwin_list = g_list_append(cwin_list, uic->cwin);
#endif
=======================================
--- /trunk/gtk/uim-cand-win-gtk.c Wed May 19 01:40:38 2010
+++ /trunk/gtk/uim-cand-win-gtk.c Sun Jun 13 00:30:03 2010
@@ -62,6 +62,16 @@
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_candidates (UIMCandWinGtk *cwin,
+ guint disp_limit,
+ GSList *candidates);
+static void uim_cand_win_gtk_real_set_page_candidates(UIMCandWinGtk *cwin,
+ guint page,
+ GSList *candidates);
+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 gboolean tree_selection_change (GtkTreeSelection
*selection,
GtkTreeModel *model,
@@ -131,6 +141,11 @@
widget_class->map = uim_cand_win_gtk_map;
widget_class->unmap = uim_cand_win_gtk_unmap;
+
+ klass->set_candidates = uim_cand_win_gtk_real_set_candidates;
+ klass->set_page_candidates = uim_cand_win_gtk_real_set_page_candidates;
+ klass->set_index = uim_cand_win_gtk_real_set_index;
+ klass->set_page = uim_cand_win_gtk_real_set_page;
}
void
@@ -309,8 +324,8 @@
return UIM_CAND_WIN_GTK(obj);
}
-static void
-update_label(UIMCandWinGtk *cwin)
+void
+uim_cand_win_gtk_update_label(UIMCandWinGtk *cwin)
{
char label_str[20];
@@ -349,14 +364,14 @@
cand_win_gtk_signals[INDEX_CHANGED_SIGNAL], 0);
}
- update_label(cwin);
+ uim_cand_win_gtk_update_label(cwin);
if (cwin->candidate_index < 0)
return FALSE;
else
return TRUE;
} else {
- update_label(cwin);
+ uim_cand_win_gtk_update_label(cwin);
return TRUE;
}
@@ -475,6 +490,14 @@
uim_cand_win_gtk_set_candidates(UIMCandWinGtk *cwin,
guint display_limit,
GSList *candidates)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->set_candidates(cwin, display_limit,
candidates);
+}
+
+static void
+uim_cand_win_gtk_real_set_candidates(UIMCandWinGtk *cwin,
+ guint display_limit,
+ GSList *candidates)
{
gint i, nr_stores = 1;
@@ -559,13 +582,21 @@
uim_cand_win_gtk_set_page(cwin, 0);
- update_label(cwin);
+ uim_cand_win_gtk_update_label(cwin);
}
void
uim_cand_win_gtk_set_page_candidates(UIMCandWinGtk *cwin,
guint page,
GSList *candidates)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->set_page_candidates(cwin, page,
candidates);
+}
+
+static void
+uim_cand_win_gtk_real_set_page_candidates(UIMCandWinGtk *cwin,
+ guint page,
+ GSList *candidates)
{
GtkListStore *store;
GSList *node;
@@ -630,6 +661,12 @@
void
uim_cand_win_gtk_set_index(UIMCandWinGtk *cwin, gint index)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->set_index(cwin, index);
+}
+
+static void
+uim_cand_win_gtk_real_set_index(UIMCandWinGtk *cwin, gint index)
{
gint new_page;
@@ -664,7 +701,7 @@
GtkTreeSelection *selection =
gtk_tree_view_get_selection(GTK_TREE_VIEW(cwin->view));
gtk_tree_selection_unselect_all(selection);
- update_label(cwin);
+ uim_cand_win_gtk_update_label(cwin);
}
}
@@ -687,6 +724,12 @@
void
uim_cand_win_gtk_set_page(UIMCandWinGtk *cwin, gint page)
+{
+ UIM_CAND_WIN_GTK_GET_CLASS (cwin)->set_page(cwin, page);
+}
+
+static void
+uim_cand_win_gtk_real_set_page(UIMCandWinGtk *cwin, gint page)
{
guint len, new_page;
gint new_index;
=======================================
--- /trunk/gtk/uim-cand-win-gtk.h Sun Apr 4 20:35:54 2010
+++ /trunk/gtk/uim-cand-win-gtk.h Sun Jun 13 00:30:03 2010
@@ -86,6 +86,16 @@
/* signals */
void (*index_changed) (UIMCandWinGtkClass *cwin);
+
+ /* member functions */
+ void (*set_candidates) (UIMCandWinGtk *cwin,
+ guint disp_limit,
+ GSList *candidates);
+ void (*set_page_candidates) (UIMCandWinGtk *cwin,
+ guint page,
+ GSList *candidates);
+ void (*set_index) (UIMCandWinGtk *cwin, gint index);
+ void (*set_page) (UIMCandWinGtk *cwin, gint page);
};
@@ -133,6 +143,8 @@
GdkRectangle *area);
void uim_cand_win_gtk_get_window_pos_type (UIMCandWinGtk *cwin);
+void uim_cand_win_gtk_update_label (UIMCandWinGtk *cwin);
+
G_END_DECLS
#endif /*UIM_GTK_UIM_CAND_WIN_GTK_H */