static void
fcitx_config_widget_setup_ui(FcitxConfigWidget *self)
{
    FcitxConfigFileDesc* cfdesc = self->cfdesc;
    GtkWidget *cvbox = GTK_WIDGET(self);
    GtkWidget *configNotebook = gtk_notebook_new();
    gtk_box_pack_start(GTK_BOX(cvbox), configNotebook, TRUE, TRUE, 0);
    if (cfdesc) {
        bindtextdomain(cfdesc->domain, LOCALEDIR);
        bind_textdomain_codeset(cfdesc->domain, "UTF-8");

        FILE *fp;
        fp = FcitxXDGGetFileWithPrefix(self->prefix, self->name, "r", NULL);
        self->gconfig.configFile = FcitxConfigParseConfigFileFp(fp, cfdesc);

        FcitxConfigGroupDesc *cgdesc = NULL;
        FcitxConfigOptionDesc *codesc = NULL;
        for (cgdesc = cfdesc->groupsDesc;
                cgdesc != NULL;
                cgdesc = (FcitxConfigGroupDesc*)cgdesc->hh.next) {
            codesc = cgdesc->optionsDesc;
            if (codesc == NULL)
                continue;

            GtkWidget* hbox = gtk_hbox_new(FALSE, 0);
            GtkWidget *table = gtk_table_new(2, HASH_COUNT(codesc), FALSE);
            GtkWidget *plabel = gtk_label_new(D_(cfdesc->domain, cgdesc->groupName));
            GtkWidget *scrollwnd = gtk_scrolled_window_new(NULL, NULL);

            gtk_container_set_border_width(GTK_CONTAINER(table), 0);
            gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
            gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrollwnd), table);
            gtk_box_pack_start(GTK_BOX(hbox), scrollwnd, TRUE, TRUE, 0);
            gtk_notebook_append_page(GTK_NOTEBOOK(configNotebook),
                                     hbox,
                                     plabel);

            int i = 0;
            for (; codesc != NULL;
                    codesc = (FcitxConfigOptionDesc*)codesc->hh.next, i++) {
                const char *s;
                if (codesc->desc && strlen(codesc->desc) != 0)
                    s = D_(cfdesc->domain, codesc->desc);
                else
                    s = D_(cfdesc->domain, codesc->optionName);

                GtkWidget *inputWidget = NULL;
                void *argument = NULL;

                switch (codesc->type) {
                case T_Integer:
                    inputWidget = gtk_spin_button_new_with_range(-1.0, 10000.0, 1.0);
                    argument = inputWidget;
                    break;
                case T_Color:
                    inputWidget = gtk_color_button_new();
                    argument = inputWidget;
                    break;
                case T_Boolean:
                    inputWidget = gtk_check_button_new();
                    argument = inputWidget;
                    break;
                case T_Font: {
                    inputWidget = gtk_hbox_new(FALSE, 0);
                    argument = gtk_font_button_new();
                    GtkWidget *button = gtk_button_new_with_label(_("Clear font setting"));
                    gtk_box_pack_start(GTK_BOX(inputWidget), argument, TRUE, TRUE, 0);
                    gtk_box_pack_start(GTK_BOX(inputWidget), button, FALSE, FALSE, 0);
                    gtk_font_button_set_use_size(GTK_FONT_BUTTON(argument), FALSE);
                    gtk_font_button_set_show_size(GTK_FONT_BUTTON(argument), FALSE);
                    g_signal_connect(G_OBJECT(button), "clicked", (GCallback) set_none_font_clicked, argument);
                }
                break;
                case T_Enum: {
                    int i;
                    FcitxConfigEnum *e = &codesc->configEnum;
#if GTK_CHECK_VERSION(2, 24, 0)
                    inputWidget = gtk_combo_box_text_new();
                    for (i = 0; i < e->enumCount; i ++) {
                        gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(inputWidget), D_(cfdesc->domain, e->enumDesc[i]));
                    }
#else
                    inputWidget = gtk_combo_box_new_text();
                    for (i = 0; i < e->enumCount; i ++)
                    {
                        gtk_combo_box_append_text(GTK_COMBO_BOX(inputWidget), D_(cfdesc->domain, e->enumDesc[i]));
                    }
#endif
                    argument = inputWidget;
                }
                break;
                case T_Hotkey: {
                    GtkWidget *button[2];
                    button[0] = keygrab_button_new();
                    button[1] = keygrab_button_new();
                    inputWidget = gtk_hbox_new(FALSE, 0);
                    gtk_box_pack_start(GTK_BOX(inputWidget), button[0], FALSE, TRUE, 0);
                    gtk_box_pack_start(GTK_BOX(inputWidget), button[1], FALSE, TRUE, 0);
                    argument = g_array_new(FALSE, FALSE, sizeof(void*));
                    g_array_append_val(argument, button[0]);
                    g_array_append_val(argument, button[1]);
                }
                break;
                case T_File:
                case T_Char:
                case T_String:
                    inputWidget = gtk_entry_new();
                    argument = inputWidget;
                    break;
                default:
                    break;
                }

                if (inputWidget) {
                    GtkWidget* label = gtk_label_new(s);
                    g_object_set(label, "xalign", 0.0f, NULL);
                    gtk_table_attach(GTK_TABLE(table), label, 0, 1, i, i + 1, GTK_FILL, GTK_SHRINK, 5, 5);
                    gtk_table_attach(GTK_TABLE(table), inputWidget, 1, 2, i, i + 1, GTK_EXPAND | GTK_FILL, GTK_SHRINK | GTK_FILL, 0, 4);
                    FcitxConfigBindValue(self->gconfig.configFile, cgdesc->groupName, codesc->optionName, NULL, sync_filter, argument);
                }
            }
        }

        FcitxConfigBindSync(&self->gconfig);
    }

    if (self->parser) {
        GHashTable* subconfigs = self->parser->subconfigs;
        if (g_hash_table_size(subconfigs) != 0) {
            GtkWidget *table = gtk_table_new(2, g_hash_table_size(subconfigs), FALSE);
            GtkWidget *plabel = gtk_label_new(_("Other"));
            GtkWidget *scrollwnd = gtk_scrolled_window_new(NULL, NULL);
            GtkWidget *viewport = gtk_viewport_new(NULL, NULL);

            gtk_container_set_border_width(GTK_CONTAINER(table), 4);
            gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrollwnd), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
            gtk_container_add(GTK_CONTAINER(scrollwnd), viewport);
            gtk_container_add(GTK_CONTAINER(viewport), table);
            gtk_notebook_append_page(GTK_NOTEBOOK(configNotebook),
                                     scrollwnd,
                                     plabel);

            HashForeachContext context;
            context.i = 0;
            context.table = table;
            context.widget = self;
            g_hash_table_foreach(subconfigs, hash_foreach_cb, &context);
        }
    }

    gtk_widget_set_size_request(configNotebook, 500, -1);
    gtk_notebook_set_scrollable(GTK_NOTEBOOK(configNotebook), TRUE);
}
static void
fcitx_wizard_candidate_widget_setup_ui(FcitxWizardCandidateWidget *self)
{
    int row = 0;
    GtkWidget *cvbox = GTK_WIDGET(self);
    GtkWidget *hbox;

    GtkWidget *grid = gtk_grid_new();
    gtk_widget_set_margin_left(grid, 0);
    gtk_widget_set_margin_top(grid, 6);
    gtk_grid_set_row_spacing(GTK_GRID(grid), 12);
    gtk_grid_set_column_spacing(GTK_GRID(grid), 6);

    GtkWidget* label = gtk_label_new(("Candidate Word Number"));
    g_object_set(label, "xalign", 0.0f, NULL);
    self->candidate_word_number_spin_button = gtk_spin_button_new_with_range(
            1, 10, 1.0);
    g_object_set(self->candidate_word_number_spin_button, "hexpand", TRUE, NULL);

    gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), self->candidate_word_number_spin_button, 1, 
        row, 1, 1);

    row ++;
    label = gtk_label_new(("Font Size"));
    g_object_set(label, "xalign", 0.0f, NULL);
    self->font_size_spin_button = gtk_spin_button_new_with_range(
            0, 72, 1.0);
    g_object_set(self->font_size_spin_button, "hexpand", TRUE, NULL);

    gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), self->font_size_spin_button, 1, 
        row, 1, 1);

    row ++;
    label = gtk_label_new(("Font"));
    g_object_set(label, "xalign", 0.0f, NULL);
    hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    self->font_button = gtk_font_button_new();
    GtkWidget *button = gtk_button_new_with_label(_("Clear font setting"));
    gtk_box_pack_start(GTK_BOX(hbox), self->font_button, TRUE, TRUE, 0);
    gtk_box_pack_start(GTK_BOX(hbox), button, FALSE, FALSE, 0);
    gtk_font_button_set_use_size(GTK_FONT_BUTTON(self->font_button), FALSE);
    gtk_font_button_set_show_size(GTK_FONT_BUTTON(self->font_button), FALSE);
    g_signal_connect(G_OBJECT(button), "clicked", (GCallback) set_none_font_clicked, 
        self->font_button);
    
    gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);    

    row ++;
    label = gtk_label_new(("Vertical Candidate Word List"));
    g_object_set(label, "xalign", 0.0f, NULL);
    self->vertical_candidate_button = gtk_check_button_new();
    g_object_set(self->vertical_candidate_button, "hexpand", TRUE, NULL);
    gtk_grid_attach(GTK_GRID(grid), label, 0, row, 1, 1);
    gtk_grid_attach(GTK_GRID(grid), self->vertical_candidate_button, 1, row, 1, 1);
    
 
    gtk_box_pack_start(GTK_BOX(cvbox), grid, TRUE, TRUE, 0);

    fcitx_wizard_candidate_widget_load_conf(self);

    g_signal_connect(G_OBJECT(self->candidate_word_number_spin_button), "value-changed",
                 G_CALLBACK(candidate_word_number_value_changed), self);
    g_signal_connect(G_OBJECT(self->font_size_spin_button), "value-changed",
                 G_CALLBACK(font_size_value_changed), self);
    g_signal_connect(G_OBJECT(self->font_button), "font-set",
                 G_CALLBACK(font_button_font_set), self);
    g_signal_connect(G_OBJECT(self->vertical_candidate_button), "toggled",
                 G_CALLBACK(vertical_candidate_button_toggled), self);

}
Example #3
0
int main(int argc,char **argv)
{
	GtkWidget *win;
	GtkWidget *vbox;
	GtkWidget *hbox;
	GtkWidget *notebook;
	GtkWidget *page;
	GtkWidget *button;
	GtkWidget *api[4];
	GtkWidget *box;
	GtkWidget *label;
	PREData data;
	char *name[]={"百度词典:","必应词典:","金山词霸:","有道词典:"};
	char *dic[]={"百度词典","必应词典","金山词霸","有道词典"};
	int i;

	/*设置默认UTF-8编码*/
	setlocale(LC_ALL,"");
#ifdef _WIN32
	putenv("LANG=zh_CN.UTF-8");
#else
	setenv("LANG","zh_CN.UTF-8");
#endif
	/*先读取出配置*/
	duoyi_read_config(&data.data);
	/*默认状态为未更改*/
	data.changed=FALSE;
	gtk_init(&argc,&argv);

	win=gtk_window_new(GTK_WINDOW_TOPLEVEL);
	gtk_window_set_title(GTK_WINDOW(win),"配置");
	gtk_window_set_position(GTK_WINDOW(win),GTK_WIN_POS_CENTER);
	gtk_window_set_icon_from_file(GTK_WINDOW(win),
			"img/64x64/preferences.png",NULL);
	gtk_window_set_resizable(GTK_WINDOW(win),FALSE);
	g_signal_connect(G_OBJECT(win),"delete-event",
			G_CALLBACK(pre_quit),&data);

	vbox=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	notebook=gtk_notebook_new();
	gtk_container_add(GTK_CONTAINER(win),vbox);

	gtk_box_pack_start(GTK_BOX(vbox),notebook,FALSE,FALSE,5);
	/*添加常规页*/
	page=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	label=gtk_label_new("常规");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page,label);
	/*添加选择字体按钮*/
	label=gtk_label_new("选择字体:");
	hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
	gtk_box_pack_start(GTK_BOX(page),hbox,FALSE,FALSE,20);
	gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,20);

	if(data.data.font)
		button=gtk_font_button_new_with_font(data.data.font);
	else
		button=gtk_font_button_new();
	/*按钮使用字体显示文字*/
	gtk_font_button_set_use_font(GTK_FONT_BUTTON(button),TRUE);
	gtk_font_button_set_title(GTK_FONT_BUTTON(button),"字体选择");
	gtk_box_pack_start(GTK_BOX(hbox),button,TRUE,TRUE,100);
	g_signal_connect(G_OBJECT(button),"font-set",
			G_CALLBACK(pre_set_font),&data);

	/*添加默认词典选择*/
	hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
	gtk_box_pack_start(GTK_BOX(page),hbox,FALSE,FALSE,20);
	label=gtk_label_new("默认词典:");
	gtk_box_pack_start(GTK_BOX(hbox),label,FALSE,FALSE,20);
	box=gtk_combo_box_text_new();
	for(i=0;i != 4;++i)
		gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(box),dic[i]);
	gtk_combo_box_set_active(GTK_COMBO_BOX(box),data.data.dic);
	g_signal_connect(G_OBJECT(box),"changed",
				G_CALLBACK(pre_set_default_dic),&data);
	//gtk_combo_box_set_active(GTK_COMBO_BOX(box),data.data.dic);
	gtk_box_pack_start(GTK_BOX(hbox),box,TRUE,TRUE,100);


	/*添加API页*/
	page=gtk_box_new(GTK_ORIENTATION_VERTICAL,0);
	label=gtk_label_new("API");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),page,label);
	for(i=0;i != 4;++i)
	{
		/*名称*/
		label=gtk_label_new(name[i]);
		/*api输入框*/
		api[i]=gtk_entry_new();
		/*api*/
		data.api[i]=api[i];
		/*如果当前API已设置,则显示出来*/
		if(data.data.api[i])
			gtk_entry_set_text(GTK_ENTRY(api[i]),data.data.api[i]);
		hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
		gtk_box_pack_start(GTK_BOX(page),hbox,TRUE,TRUE,10);
		gtk_box_pack_start(GTK_BOX(hbox),label,TRUE,TRUE,10);
		gtk_box_pack_start(GTK_BOX(hbox),api[i],TRUE,TRUE,10);
		/*如有改动更改操作状态*/
		g_signal_connect(G_OBJECT(api[i]),"changed",
				G_CALLBACK(pre_save_flag),&data);
	}

	hbox=gtk_box_new(GTK_ORIENTATION_HORIZONTAL,0);
	gtk_box_pack_end(GTK_BOX(vbox),hbox,FALSE,FALSE,5);
	gtk_box_pack_end(GTK_BOX(vbox),
			gtk_separator_new(GTK_ORIENTATION_HORIZONTAL),
			FALSE,FALSE,5);
	label=gtk_label_new("所有更改均在重启后生效!");
	gtk_box_pack_end(GTK_BOX(vbox),label,FALSE,FALSE,5);

	/*取消按钮*/
	button=gtk_button_new_with_label("取消");
	gtk_box_pack_start(GTK_BOX(hbox),button,FALSE,FALSE,20);
	g_signal_connect(G_OBJECT(button),"clicked",
			G_CALLBACK(pre_quit),&data);

	/*保存按钮*/
	button=gtk_button_new_with_label("保存");
	gtk_box_pack_end(GTK_BOX(hbox),button,FALSE,FALSE,20);
	g_signal_connect(G_OBJECT(button),"clicked",
			G_CALLBACK(pre_quit_with_save),&data);

	gtk_widget_show_all(win);
	gtk_main();

	return 0;
}
static GtkWidget* get_widget()
{
    GtkWidget *widget;
    GtkWidget *table;
    GtkWidget *spacer;
    GtkWidget *indent_width;
    GtkWidget *tab_width;
    GtkWidget *tab_width_label;
    GtkWidget *indent_width_label;
    GtkWidget *draw_spaces;
    GtkWidget *draw_spaces_label;
    GtkWidget *font;
    GtkWidget *font_label;

    widget = gtk_vbox_new( FALSE, 0 );

    table = gtk_table_new( 6, 2, FALSE );
    gtk_box_pack_start( GTK_BOX( widget ), table, FALSE, FALSE, 0 );

    spacer = gtk_vbox_new( FALSE, 0 );
    gtk_box_pack_start( GTK_BOX( widget ), spacer, TRUE, TRUE, 0 );

    font = gtk_hbox_new( FALSE, 0 );
    gtk_table_attach_defaults( GTK_TABLE( table ), font, 0, 2, 0, 1 );

    font_label = gtk_label_new( _("Font") );
    gtk_box_pack_start( GTK_BOX( font ), font_label, FALSE, FALSE, 0 );

    font_editor = gtk_font_button_new();
    gtk_box_pack_start( GTK_BOX( font ), font_editor, TRUE, TRUE, 1 );

    auto_indent = gtk_check_button_new_with_label( _("Auto indent") );
    gtk_table_attach_defaults( GTK_TABLE( table ), auto_indent, 0, 1, 1, 2 );

    indent_on_tab = gtk_check_button_new_with_label( _("Indent on tab") );
    gtk_table_attach_defaults( GTK_TABLE( table ), indent_on_tab, 1, 2, 1, 2 );

    show_line_numbers = gtk_check_button_new_with_label( _("Show line numbers") );
    gtk_table_attach_defaults( GTK_TABLE( table ), show_line_numbers, 0, 1, 2, 3 );

    smart_home_end = gtk_check_button_new_with_label( _("Smart home/end") );
    gtk_table_attach_defaults( GTK_TABLE( table ), smart_home_end, 1, 2, 2, 3 );

    highlight_current_line = gtk_check_button_new_with_label( _("Highlight current line") );
    gtk_table_attach_defaults( GTK_TABLE( table ), highlight_current_line, 0, 1, 3, 4 );

    insert_spaces_instead_of_tabs = gtk_check_button_new_with_label( _("Insert spaces instead of tabs") );
    gtk_table_attach_defaults( GTK_TABLE( table ), insert_spaces_instead_of_tabs, 1, 2, 3, 4 );

    indent_width = gtk_hbox_new( FALSE, 0 );
    gtk_table_attach_defaults( GTK_TABLE( table ), indent_width, 0, 1, 4, 5 );

    indent_width_label = gtk_label_new( _("Indent width") );
    gtk_box_pack_start( GTK_BOX( indent_width ), indent_width_label, FALSE, FALSE, 0 );

    indent_width_editor = gtk_spin_button_new_with_range( 0, 999999999, 1 );
    gtk_box_pack_start( GTK_BOX( indent_width ), indent_width_editor, TRUE, TRUE, 1 );

    tab_width = gtk_hbox_new( FALSE, 0 );
    gtk_table_attach_defaults( GTK_TABLE( table ), tab_width, 1, 2, 4, 5 );

    tab_width_label = gtk_label_new( _("Tab width") );
    gtk_box_pack_start( GTK_BOX( tab_width ), tab_width_label, FALSE, FALSE, 0 );

    tab_width_editor = gtk_spin_button_new_with_range( 0, 999999999, 1 );
    gtk_box_pack_start( GTK_BOX( tab_width ), tab_width_editor, TRUE, TRUE, 1 );

    draw_spaces = gtk_hbox_new( FALSE, 0 );
    gtk_table_attach_defaults( GTK_TABLE( table ), draw_spaces, 0, 1, 5, 6 );

    draw_spaces_label = gtk_label_new( _("Draw spaces mode") );
    gtk_box_pack_start( GTK_BOX( draw_spaces ), draw_spaces_label, FALSE, FALSE, 0 );

    draw_spaces_editor = gtk_combo_box_new_text();
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("No") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Space") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Tab") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("New line") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Non-breaking") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Leading") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Inside text") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("Trailing") );
    gtk_combo_box_append_text( GTK_COMBO_BOX( draw_spaces_editor ), _("All") );
    gtk_combo_box_set_active( GTK_COMBO_BOX( draw_spaces_editor ), 0 );
    gtk_box_pack_start( GTK_BOX( draw_spaces ), draw_spaces_editor, TRUE, TRUE, 0 );

    return widget;
}
Example #5
0
GtkWidget * build_tgroup(MtxTickGroup *tgroup, gint index)
{
	/* MUCH faster that the ui way unfortunately */
	GtkWidget *notebook = NULL;
	GtkWidget *table = NULL;
	GtkWidget *subtable = NULL;
	GtkWidget *widget = NULL;
	GtkWidget *x_spin = NULL;
	GtkWidget *y_spin = NULL;
	GtkWidget *hbox = NULL;
	GtkWidget *img = NULL;
	GtkWidget *label = NULL;
	GtkWidget *start = NULL;
	GtkWidget *sweep = NULL;
	GtkWidget *low = NULL;
	GtkWidget *high = NULL;
	gchar * tmpbuf = NULL;

	table = gtk_table_new(2,2,FALSE);

	/* Close button */
	widget = gtk_button_new();
	img = gtk_image_new_from_stock("gtk-close",GTK_ICON_SIZE_MENU);
	gtk_container_add(GTK_CONTAINER(widget),img);
	OBJ_SET((widget),"tgroup_index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"clicked", G_CALLBACK(remove_tgroup),NULL);
	gtk_table_attach(GTK_TABLE(table),widget,0,1,0,4,0,0,0,0);

	notebook = gtk_notebook_new();
	gtk_table_attach(GTK_TABLE(table),notebook,1,2,0,1,GTK_EXPAND|GTK_FILL,0,0,0);
	/* Text/Color Tab */
	subtable = gtk_table_new(2,4,FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(subtable),5);
	label = gtk_label_new("Text & Color");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);
	widget = gtk_label_new("Text:");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,0,2,GTK_FILL,GTK_EXPAND|GTK_FILL,0,0);

	widget = gtk_entry_new();
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_TEXT));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	gtk_entry_set_width_chars(GTK_ENTRY(widget),12);
	gtk_entry_set_text(GTK_ENTRY(widget),tgroup->text);
	g_signal_connect(G_OBJECT(widget),"changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,0,2,GTK_EXPAND|GTK_FILL,GTK_EXPAND|GTK_FILL,0,0);
	widget = gtk_label_new("Day");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,0,1,0,GTK_FILL,0,0);

	widget = gtk_color_button_new_with_color(&tgroup->text_color[MTX_DAY]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_TEXT_COLOR_DAY));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,1,2,GTK_FILL,GTK_EXPAND,0,0);

	widget = gtk_label_new("Night");
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,0,1,0,GTK_FILL,0,0);
	widget = gtk_color_button_new_with_color(&tgroup->text_color[MTX_NITE]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_TEXT_COLOR_NITE));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,1,2,GTK_FILL,GTK_EXPAND,0,0);

	/* Font Tab */
	subtable = gtk_table_new(1,4,FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(subtable),5);
	label = gtk_label_new("Font");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);

	widget = gtk_label_new("Font:");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,0,1,GTK_FILL,GTK_EXPAND,0,0);

	widget = gtk_font_button_new();
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_FONT));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	tmpbuf = g_strdup_printf("%s 12",tgroup->font);
	gtk_font_button_set_font_name(GTK_FONT_BUTTON(widget),tmpbuf);
	gtk_font_button_set_show_size(GTK_FONT_BUTTON(widget),FALSE);
	gtk_font_button_set_use_size(GTK_FONT_BUTTON(widget),FALSE);
	gtk_font_button_set_use_font(GTK_FONT_BUTTON(widget),FALSE);
	g_free(tmpbuf);
	g_signal_connect(G_OBJECT(widget),"font_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,0,1,GTK_EXPAND|GTK_FILL,GTK_EXPAND,0,0);

	widget = gtk_label_new("Font\nScale");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,0,1,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.001,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_FONT_SCALE));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->font_scale, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,0,1,0,GTK_EXPAND,0,0);

	widget = gtk_label_new("Text\nInset");
	gtk_table_attach(GTK_TABLE(subtable),widget,4,5,0,1,0,GTK_EXPAND,0,0);
	widget = gtk_spin_button_new_with_range(0.001,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_TEXT_INSET));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->text_inset, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,5,6,0,1,0,GTK_EXPAND,0,0);

	/* Major Ticks Tab */
	subtable = gtk_table_new(2,6,FALSE);
	/*gtk_table_set_col_spacings(GTK_TABLE(subtable),5);*/
	label = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(label),"<b>Major</b> Ticks");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);

	/* Labels */
	widget = gtk_label_new("Total Ticks");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Length");
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Width");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Inset");
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Day");
	gtk_table_attach(GTK_TABLE(subtable),widget,4,5,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Night");
	gtk_table_attach(GTK_TABLE(subtable),widget,5,6,0,1,GTK_EXPAND,GTK_EXPAND,0,0);

	/* Spinners */
	widget = gtk_spin_button_new_with_range(0.0,100.0,1);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_NUM_MAJ_TICKS));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 1.0, "digits", 0, "numeric", TRUE, NULL);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),tgroup->num_maj_ticks);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MAJ_TICK_LENGTH));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->maj_tick_length, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MAJ_TICK_WIDTH));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->maj_tick_width, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MAJ_TICK_INSET));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->maj_tick_inset, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_color_button_new_with_color(&tgroup->maj_tick_color[MTX_DAY]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MAJ_TICK_COLOR_DAY));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,4,5,1,2,GTK_FILL,GTK_EXPAND,0,0);

	widget = gtk_color_button_new_with_color(&tgroup->maj_tick_color[MTX_NITE]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MAJ_TICK_COLOR_NITE));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,5,6,1,2,GTK_FILL,GTK_EXPAND,0,0);

	/* Minor Ticks Tab */
	subtable = gtk_table_new(2,6,FALSE);
	/*gtk_table_set_col_spacings(GTK_TABLE(subtable),5);*/
	label = gtk_label_new(NULL);
	gtk_label_set_markup(GTK_LABEL(label),"<b>Minor</b> Ticks");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);

	/* Labels */
	widget = gtk_label_new("Total Ticks");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Length");
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Width");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Inset");
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Day");
	gtk_table_attach(GTK_TABLE(subtable),widget,4,5,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Night");
	gtk_table_attach(GTK_TABLE(subtable),widget,5,6,0,1,GTK_EXPAND,GTK_EXPAND,0,0);

	/* Spinners */
	widget = gtk_spin_button_new_with_range(0.0,100.0,1);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_NUM_MIN_TICKS));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 1.0, "digits", 0, "numeric", TRUE, NULL);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),tgroup->num_min_ticks);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MIN_TICK_LENGTH));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->min_tick_length, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MIN_TICK_WIDTH));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->min_tick_width, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(0.0,1.0,0.001);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MIN_TICK_INSET));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 0.001, "digits", 3, "numeric", TRUE, "value", tgroup->min_tick_inset, NULL);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,1,2,0,GTK_EXPAND,0,0);

	widget = gtk_color_button_new_with_color(&tgroup->min_tick_color[MTX_DAY]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MIN_TICK_COLOR_DAY));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,4,5,1,2,GTK_FILL,GTK_EXPAND,0,0);

	widget = gtk_color_button_new_with_color(&tgroup->min_tick_color[MTX_NITE]);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_MIN_TICK_COLOR_NITE));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_signal_connect(G_OBJECT(widget),"color_set",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,5,6,1,2,GTK_FILL,GTK_EXPAND,0,0);

	/* Tick Span Tab */
	subtable = gtk_table_new(3,4,FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(subtable),5);
	label = gtk_label_new("Tick Span");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);

	widget = gtk_label_new("Angular Span (deg.)");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,2,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Span (Gauge Units)");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,4,0,1,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Start Angle");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,1,2,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Sweep Angle");
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,1,2,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("Low Point");
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,1,2,GTK_EXPAND,GTK_EXPAND,0,0);
	widget = gtk_label_new("High Point");
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,1,2,GTK_EXPAND,GTK_EXPAND,0,0);
	/* Span Spinners */
	widget = gtk_spin_button_new_with_range(-360.0,360.0,0.1);
	start = widget;
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_START_ANGLE));
	OBJ_SET(widget,"spin_handler",GINT_TO_POINTER(ADJ_LOW_UNIT_PARTNER));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,2,3,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(-360.0,360.0,0.1);
	sweep = widget;
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_SWEEP_ANGLE));
	OBJ_SET(widget,"spin_handler",GINT_TO_POINTER(ADJ_HIGH_UNIT_PARTNER));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,2,3,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(-99999.0,99999.0,0.1);
	low = widget;
	OBJ_SET(widget,"handler",GINT_TO_POINTER(ADJ_START_ANGLE_PARTNER));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(low),"climb-rate", 0.1, "digits", 1, "numeric", TRUE, NULL);
	g_signal_connect(G_OBJECT(low),"value-changed",G_CALLBACK(tg_spin_button_handler),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,2,3,2,3,0,GTK_EXPAND,0,0);

	widget = gtk_spin_button_new_with_range(-99999.0,99999.0,0.1);
	high = widget;
	OBJ_SET(widget,"handler",GINT_TO_POINTER(ADJ_SWEEP_ANGLE_PARTNER));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(high),"climb-rate", 0.1, "digits", 1, "numeric", TRUE, NULL);
	g_signal_connect(G_OBJECT(high),"value-changed",G_CALLBACK(tg_spin_button_handler),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,3,4,2,3,0,GTK_EXPAND,0,0);

	/* Start/Sweep <-> Low/High interconnectedness 
	 * This is done like shit and I don't like it..
	 */
	OBJ_SET(start,"lowpartner",low);
	OBJ_SET(start,"highpartner",high);
	OBJ_SET(start,"high_angle",sweep);
	OBJ_SET(sweep,"highpartner",high);
	OBJ_SET(sweep,"low_angle",start);
	OBJ_SET(low,"lowpartner",start);
	OBJ_SET(high,"highpartner",sweep);
	OBJ_SET(high,"start_angle",start);
	/* Connect the signals, then set the values to trigger the linked
	 * spinners to update, THEN enable change handlers, as the gauge
	 * ALREADY has the info, no need to set it again..
	 */
	g_signal_connect(G_OBJECT(start),"value-changed",G_CALLBACK(tg_spin_button_handler),NULL);
	g_signal_connect(G_OBJECT(sweep),"value-changed",G_CALLBACK(tg_spin_button_handler),NULL);
	g_object_set(G_OBJECT(start),"climb-rate", 0.1, "digits", 1, "numeric", TRUE, "value", tgroup->start_angle, NULL);
	g_object_set(G_OBJECT(sweep),"climb-rate", 0.1, "digits", 1, "numeric", TRUE, "value", tgroup->sweep_angle, NULL);
	g_signal_connect(G_OBJECT(start),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	g_signal_connect(G_OBJECT(sweep),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);

	/* Layer Tab: Layer */
	subtable = gtk_table_new(1,4,FALSE);
	gtk_table_set_col_spacings(GTK_TABLE(subtable),5);
	label = gtk_label_new("Layer");
	gtk_notebook_append_page(GTK_NOTEBOOK(notebook),subtable,label);
	gtk_notebook_set_tab_label_packing(GTK_NOTEBOOK(notebook),subtable,TRUE,TRUE,GTK_PACK_START);

	widget = gtk_label_new("Layer:");
	gtk_table_attach(GTK_TABLE(subtable),widget,0,1,0,1,GTK_FILL,0,0,0);
	widget = gtk_spin_button_new_with_range(0.0,10.0,1.0);
	OBJ_SET(widget,"handler",GINT_TO_POINTER(TG_LAYER));
	OBJ_SET(widget,"index",GINT_TO_POINTER(index));
	g_object_set(G_OBJECT(widget),"climb-rate", 1.0, "digits", 0, "numeric", TRUE, NULL);
	gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget),(gfloat)tgroup->layer);
	g_signal_connect(G_OBJECT(widget),"value-changed",G_CALLBACK(alter_tgroup_data),NULL);
	gtk_table_attach(GTK_TABLE(subtable),widget,1,2,0,1,GTK_FILL,0,0,0);

	widget = gtk_hseparator_new();
	gtk_table_attach(GTK_TABLE(table),widget,0,2,1,2,GTK_FILL,0,0,0);
	return table;
}
static void
fcitx_config_widget_create_option_widget(
    FcitxConfigWidget *self,
    FcitxConfigGroupDesc* cgdesc,
    FcitxConfigOptionDesc* codesc,
    char** label,
    char** tooltip,
    GtkWidget** inputWidget,
    void** newarg)
{
    FcitxConfigFileDesc* cfdesc = self->cfdesc;
    FcitxConfigOptionDesc2* codesc2 = (FcitxConfigOptionDesc2*) codesc;
    void* oldarg = NULL;
    void* argument = NULL;
    char* name = g_strdup_printf("%s/%s", cgdesc->groupName, codesc->optionName);
    oldarg = g_hash_table_lookup(self->argmap, name);

    if (codesc->desc && strlen(codesc->desc) != 0) {
        *label = strdup(D_(cfdesc->domain, codesc->desc));
    } else {
        *label = strdup(D_(cfdesc->domain, codesc->optionName));
    }

    if (codesc2->longDesc && codesc2->longDesc[0]) {
        *tooltip = strdup(D_(cfdesc->domain, codesc2->longDesc));
    }

    switch (codesc->type) {
    case T_Integer:
        *inputWidget = gtk_spin_button_new_with_range(
            codesc2->constrain.integerConstrain.min,
            codesc2->constrain.integerConstrain.max,
            1.0);
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        if (oldarg) {
            g_object_bind_property(*inputWidget, "value", oldarg, "value", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(*inputWidget, "notify::value", (GCallback) _fcitx_config_widget_changed, self);
            argument = *inputWidget;
        }
        break;
    case T_Color:
        *inputWidget = gtk_color_button_new();
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        if (oldarg) {
            g_object_bind_property(*inputWidget, "color", oldarg, "color", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(*inputWidget, "notify::color", (GCallback) _fcitx_config_widget_changed, self);
            argument = *inputWidget;
        }
        break;
    case T_Boolean:
        *inputWidget = gtk_check_button_new();
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        if (oldarg) {
            g_object_bind_property(*inputWidget, "active", oldarg, "active", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(*inputWidget, "notify::active", (GCallback) _fcitx_config_widget_changed, self);
            argument = *inputWidget;
        }
        break;
    case T_Font: {
        *inputWidget = gtk_grid_new();
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        GtkWidget* arg = gtk_font_button_new();
        GtkWidget *button = gtk_button_new_with_label(_("Clear font setting"));
        g_object_set(arg, "hexpand", TRUE, NULL);
        gtk_grid_attach(GTK_GRID(*inputWidget), arg, 0, 0, 1, 1);
        gtk_grid_attach(GTK_GRID(*inputWidget), button, 1, 0, 2, 1);
        gtk_font_button_set_use_size(GTK_FONT_BUTTON(arg), FALSE);
        gtk_font_button_set_show_size(GTK_FONT_BUTTON(arg), FALSE);
        g_signal_connect(G_OBJECT(button), "clicked", (GCallback) set_none_font_clicked, arg);
        if (oldarg) {
            g_object_bind_property(arg, "font-name", oldarg, "font-name", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(arg, "notify::font-name", (GCallback) _fcitx_config_widget_changed, self);
            argument = arg;
        }
    }
    break;
    case T_Enum: {
        int i;
        FcitxConfigEnum *e = &codesc->configEnum;
        *inputWidget = gtk_combo_box_text_new();
        for (i = 0; i < e->enumCount; i ++) {
            gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(*inputWidget), D_(cfdesc->domain, e->enumDesc[i]));
        }
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        if (oldarg) {
            g_object_bind_property(*inputWidget, "active", oldarg, "active", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(*inputWidget, "notify::active", (GCallback) _fcitx_config_widget_changed, self);
            argument = *inputWidget;
        }
    }
    break;
    case T_Hotkey: {
        GtkWidget *button[2];
        button[0] = keygrab_button_new();
        button[1] = keygrab_button_new();
        *inputWidget = gtk_grid_new();
        gtk_grid_attach(GTK_GRID(*inputWidget), button[0], 0, 0, 1, 1);
        gtk_grid_attach(GTK_GRID(*inputWidget), button[1], 1, 0, 2, 1);
        g_object_set(G_OBJECT(button[0]), "hexpand", TRUE, NULL);
        g_object_set(G_OBJECT(button[1]), "hexpand", TRUE, NULL);
        if (oldarg) {
            GArray* array = oldarg;
            int j;
            for (j = 0; j < 2; j ++) {
                GtkWidget *oldbutton = g_array_index(array, GtkWidget*, j);
                g_signal_connect(oldbutton, "changed", (GCallback) sync_hotkey, button[j]);
                g_signal_connect(button[j], "changed", (GCallback) sync_hotkey, oldbutton);
            }
        }
        else {
            argument = g_array_new(FALSE, FALSE, sizeof(void*));
            int j;
            for (j = 0; j < 2; j ++) {
                g_signal_connect(button[j], "changed", (GCallback) _fcitx_config_widget_hotkey_changed, self);
                g_array_append_val(argument, button[j]);
            }
        }
    }
    break;
    case T_File:
    case T_Char:
    case T_String:
        *inputWidget = gtk_entry_new();
        g_object_set(*inputWidget, "hexpand", TRUE, NULL);
        if (oldarg) {
            g_object_bind_property(*inputWidget, "text", oldarg, "text", G_BINDING_BIDIRECTIONAL);
        } else {
            g_signal_connect(*inputWidget, "notify::text", (GCallback) _fcitx_config_widget_changed, self);
            argument = *inputWidget;
        }
        break;
    default:
        break;
    }