⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkdlg.c

📁 putty
💻 C
📖 第 1 页 / 共 5 页
字号:
    return FALSE;
}

static void list_selchange(GtkList *list, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(list));
    if (!uc) return;
    uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_SELCHANGE);
}

static void menuitem_activate(GtkMenuItem *item, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    GtkWidget *menushell = GTK_WIDGET(item)->parent;
    gpointer optmenu = gtk_object_get_data(GTK_OBJECT(menushell), "user-data");
    struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(optmenu));
    uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_SELCHANGE);
}

static void draglist_move(struct dlgparam *dp, struct uctrl *uc, int direction)
{
    int index = dlg_listbox_index(uc->ctrl, dp);
    GList *children = gtk_container_children(GTK_CONTAINER(uc->list));
    GtkWidget *child;

    if ((index < 0) ||
	(index == 0 && direction < 0) ||
	(index == g_list_length(children)-1 && direction > 0)) {
	gdk_beep();
	return;
    }

    child = g_list_nth_data(children, index);
    gtk_widget_ref(child);
    gtk_list_clear_items(GTK_LIST(uc->list), index, index+1);
    g_list_free(children);

    children = NULL;
    children = g_list_append(children, child);
    gtk_list_insert_items(GTK_LIST(uc->list), children, index + direction);
    gtk_list_select_item(GTK_LIST(uc->list), index + direction);
    uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_VALCHANGE);
}

static void draglist_up(GtkButton *button, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(button));
    draglist_move(dp, uc, -1);
}

static void draglist_down(GtkButton *button, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(button));
    draglist_move(dp, uc, +1);
}

static void filesel_ok(GtkButton *button, gpointer data)
{
    /* struct dlgparam *dp = (struct dlgparam *)data; */
    gpointer filesel = gtk_object_get_data(GTK_OBJECT(button), "user-data");
    struct uctrl *uc = gtk_object_get_data(GTK_OBJECT(filesel), "user-data");
    char *name = gtk_file_selection_get_filename(GTK_FILE_SELECTION(filesel));
    gtk_entry_set_text(GTK_ENTRY(uc->entry), name);
}

static void fontsel_ok(GtkButton *button, gpointer data)
{
    /* struct dlgparam *dp = (struct dlgparam *)data; */
    gpointer fontsel = gtk_object_get_data(GTK_OBJECT(button), "user-data");
    struct uctrl *uc = gtk_object_get_data(GTK_OBJECT(fontsel), "user-data");
    char *name = gtk_font_selection_dialog_get_font_name
	(GTK_FONT_SELECTION_DIALOG(fontsel));
    gtk_entry_set_text(GTK_ENTRY(uc->entry), name);
}

static void coloursel_ok(GtkButton *button, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    gpointer coloursel = gtk_object_get_data(GTK_OBJECT(button), "user-data");
    struct uctrl *uc = gtk_object_get_data(GTK_OBJECT(coloursel), "user-data");
    gdouble cvals[4];
    gtk_color_selection_get_color
	(GTK_COLOR_SELECTION(GTK_COLOR_SELECTION_DIALOG(coloursel)->colorsel),
	 cvals);
    dp->coloursel_result.r = (int) (255 * cvals[0]);
    dp->coloursel_result.g = (int) (255 * cvals[1]);
    dp->coloursel_result.b = (int) (255 * cvals[2]);
    dp->coloursel_result.ok = TRUE;
    uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_CALLBACK);
}

static void coloursel_cancel(GtkButton *button, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    gpointer coloursel = gtk_object_get_data(GTK_OBJECT(button), "user-data");
    struct uctrl *uc = gtk_object_get_data(GTK_OBJECT(coloursel), "user-data");
    dp->coloursel_result.ok = FALSE;
    uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_CALLBACK);
}

static void filefont_clicked(GtkButton *button, gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(button));

    if (uc->ctrl->generic.type == CTRL_FILESELECT) {
	GtkWidget *filesel =
	    gtk_file_selection_new(uc->ctrl->fileselect.title);
	gtk_window_set_modal(GTK_WINDOW(filesel), TRUE);
	gtk_object_set_data
	    (GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "user-data",
	     (gpointer)filesel);
	gtk_object_set_data(GTK_OBJECT(filesel), "user-data", (gpointer)uc);
	gtk_signal_connect
	    (GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked",
	     GTK_SIGNAL_FUNC(filesel_ok), (gpointer)dp);
	gtk_signal_connect_object
	    (GTK_OBJECT(GTK_FILE_SELECTION(filesel)->ok_button), "clicked",
	     GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer)filesel);
	gtk_signal_connect_object
	    (GTK_OBJECT(GTK_FILE_SELECTION(filesel)->cancel_button), "clicked",
	     GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer)filesel);
	gtk_widget_show(filesel);
    }

    if (uc->ctrl->generic.type == CTRL_FONTSELECT) {
	gchar *spacings[] = { "c", "m", NULL };
        gchar *fontname = gtk_entry_get_text(GTK_ENTRY(uc->entry));
	GtkWidget *fontsel =
	    gtk_font_selection_dialog_new("Select a font");
	gtk_window_set_modal(GTK_WINDOW(fontsel), TRUE);
	gtk_font_selection_dialog_set_filter
	    (GTK_FONT_SELECTION_DIALOG(fontsel),
	     GTK_FONT_FILTER_BASE, GTK_FONT_ALL,
	     NULL, NULL, NULL, NULL, spacings, NULL);
	if (!gtk_font_selection_dialog_set_font_name
	    (GTK_FONT_SELECTION_DIALOG(fontsel), fontname)) {
            /*
             * If the font name wasn't found as it was, try opening
             * it and extracting its FONT property. This should
             * have the effect of mapping short aliases into true
             * XLFDs.
             */
            GdkFont *font = gdk_font_load(fontname);
            if (font) {
                XFontStruct *xfs = GDK_FONT_XFONT(font);
                Display *disp = GDK_FONT_XDISPLAY(font);
                Atom fontprop = XInternAtom(disp, "FONT", False);
                unsigned long ret;
                if (XGetFontProperty(xfs, fontprop, &ret)) {
                    char *name = XGetAtomName(disp, (Atom)ret);
                    if (name)
                        gtk_font_selection_dialog_set_font_name
                        (GTK_FONT_SELECTION_DIALOG(fontsel), name);
                }
                gdk_font_unref(font);
            }
        }
	gtk_object_set_data
	    (GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button),
	     "user-data", (gpointer)fontsel);
	gtk_object_set_data(GTK_OBJECT(fontsel), "user-data", (gpointer)uc);
	gtk_signal_connect
	    (GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button),
	     "clicked", GTK_SIGNAL_FUNC(fontsel_ok), (gpointer)dp);
	gtk_signal_connect_object
	    (GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->ok_button),
	     "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
	     (gpointer)fontsel);
	gtk_signal_connect_object
	    (GTK_OBJECT(GTK_FONT_SELECTION_DIALOG(fontsel)->cancel_button),
	     "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy),
	     (gpointer)fontsel);
	gtk_widget_show(fontsel);
    }
}

static void label_sizealloc(GtkWidget *widget, GtkAllocation *alloc,
			    gpointer data)
{
    struct dlgparam *dp = (struct dlgparam *)data;
    struct uctrl *uc = dlg_find_bywidget(dp, widget);

    gtk_widget_set_usize(uc->text, alloc->width, -1);
    gtk_label_set_text(GTK_LABEL(uc->text), uc->ctrl->generic.label);
    gtk_signal_disconnect(GTK_OBJECT(uc->text), uc->textsig);
}

/* ----------------------------------------------------------------------
 * This function does the main layout work: it reads a controlset,
 * it creates the relevant GTK controls, and returns a GtkWidget
 * containing the result. (This widget might be a title of some
 * sort, it might be a Columns containing many controls, or it
 * might be a GtkFrame containing a Columns; whatever it is, it's
 * definitely a GtkWidget and should probably be added to a
 * GtkVbox.)
 * 
 * `listitemheight' is used to calculate a usize for list boxes: it
 * should be the height from the size request of a GtkListItem.
 * 
 * `win' is required for setting the default button. If it is
 * non-NULL, all buttons created will be default-capable (so they
 * have extra space round them for the default highlight).
 */
GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
			struct controlset *s, int listitemheight,
			GtkWindow *win)
{
    Columns *cols;
    GtkWidget *ret;
    int i;

    if (!s->boxname && s->boxtitle) {
        /* This controlset is a panel title. */
        return gtk_label_new(s->boxtitle);
    }

    /*
     * Otherwise, we expect to be laying out actual controls, so
     * we'll start by creating a Columns for the purpose.
     */
    cols = COLUMNS(columns_new(4));
    ret = GTK_WIDGET(cols);
    gtk_widget_show(ret);

    /*
     * Create a containing frame if we have a box name.
     */
    if (*s->boxname) {
        ret = gtk_frame_new(s->boxtitle);   /* NULL is valid here */
        gtk_container_set_border_width(GTK_CONTAINER(cols), 4);
        gtk_container_add(GTK_CONTAINER(ret), GTK_WIDGET(cols));
        gtk_widget_show(ret);
    }

    /*
     * Now iterate through the controls themselves, create them,
     * and add them to the Columns.
     */
    for (i = 0; i < s->ncontrols; i++) {
	union control *ctrl = s->ctrls[i];
	struct uctrl *uc;
	int left = FALSE;
        GtkWidget *w = NULL;

        switch (ctrl->generic.type) {
          case CTRL_COLUMNS:
            {
                static const int simplecols[1] = { 100 };
                columns_set_cols(cols, ctrl->columns.ncols,
                                 (ctrl->columns.percentages ?
                                  ctrl->columns.percentages : simplecols));
            }
            continue;                  /* no actual control created */
          case CTRL_TABDELAY:
	    {
		struct uctrl *uc = dlg_find_byctrl(dp, ctrl->tabdelay.ctrl);
		if (uc)
		    columns_taborder_last(cols, uc->toplevel);
	    }
            continue;                  /* no actual control created */
	}

	uc = snew(struct uctrl);
	uc->ctrl = ctrl;
	uc->privdata = NULL;
	uc->privdata_needs_free = FALSE;
	uc->buttons = NULL;
	uc->entry = uc->list = uc->menu = NULL;
	uc->button = uc->optmenu = uc->text = NULL;
	uc->label = NULL;
        uc->nclicks = 0;

        switch (ctrl->generic.type) {
          case CTRL_BUTTON:
            w = gtk_button_new_with_label(ctrl->generic.label);
	    if (win) {
		GTK_WIDGET_SET_FLAGS(w, GTK_CAN_DEFAULT);
		if (ctrl->button.isdefault)
		    gtk_window_set_default(win, w);
		if (ctrl->button.iscancel)
		    dp->cancelbutton = w;
	    }
	    gtk_signal_connect(GTK_OBJECT(w), "clicked",
			       GTK_SIGNAL_FUNC(button_clicked), dp);
            gtk_signal_connect(GTK_OBJECT(w), "focus_in_event",
                               GTK_SIGNAL_FUNC(widget_focus), dp);
	    shortcut_add(scs, GTK_BIN(w)->child, ctrl->button.shortcut,
			 SHORTCUT_UCTRL, uc);
            break;
          case CTRL_CHECKBOX:
            w = gtk_check_button_new_with_label(ctrl->generic.label);
	    gtk_signal_connect(GTK_OBJECT(w), "toggled",
			       GTK_SIGNAL_FUNC(button_toggled), dp);
            gtk_signal_connect(GTK_OBJECT(w), "focus_in_event",
                               GTK_SIGNAL_FUNC(widget_focus), dp);
	    shortcut_add(scs, GTK_BIN(w)->child, ctrl->checkbox.shortcut,
			 SHORTCUT_UCTRL, uc);
	    left = TRUE;
            break;
          case CTRL_RADIO:
            /*
             * Radio buttons get to go inside their own Columns, no
             * matter what.
             */
            {
                gint i, *percentages;
                GSList *group;

                w = columns_new(0);
                if (ctrl->generic.label) {
                    GtkWidget *label = gtk_label_new(ctrl->generic.label);
                    columns_add(COLUMNS(w), label, 0, 1);
		    columns_force_left_align(COLUMNS(w), label);
                    gtk_widget_show(label);
		    shortcut_add(scs, label, ctrl->radio.shortcut,
				 SHORTCUT_UCTRL, uc);
		    uc->label = label;
                }
                percentages = g_new(gint, ctrl->radio.ncolumns);
                for (i = 0; i < ctrl->radio.ncolumns; i++) {
                    percentages[i] =
                        ((100 * (i+1) / ctrl->radio.ncolumns) -
                         100 * i / ctrl->radio.ncolumns);
                }
                columns_set_cols(COLUMNS(w), ctrl->radio.ncolumns,
                                 percentages);
                g_free(percentages);
                group = NULL;

		uc->nbuttons = ctrl->radio.nbuttons;
		uc->buttons = snewn(uc->nbuttons, GtkWidget *);

                for (i = 0; i < ctrl->radio.nbuttons; i++) {
                    GtkWidget *b;
                    gint colstart;

                    b = (gtk_radio_button_new_with_label
                         (group, ctrl->radio.buttons[i]));
		    uc->buttons[i] = b;
                    group = gtk_radio_button_group(GTK_RADIO_BUTTON(b));
                    colstart = i % ctrl->radio.ncolumns;
                    columns_add(COLUMNS(w), b, colstart,
                                (i == ctrl->radio.nbuttons-1 ?
                                 ctrl->radio.ncolumns - colstart : 1));
		    columns_force_left_align(COLUMNS(w), b);
                    gtk_widget_show(b);
		    gtk_signal_connect(GTK_OBJECT(b), "toggled",
				       GTK_SIGNAL_FUNC(button_toggled), dp);
                    gtk_signal_connect(GTK_OBJECT(b), "focus_in_event",
                                       GTK_SIGNAL_FUNC(widget_focus), dp);
		    if (ctrl->radio.shortcuts) {
			shortcut_add(scs, GTK_BIN(b)->child,
				     ctrl->radio.shortcuts[i],
				     SHORTCUT_UCTRL, uc);
		    }
                }
            }
            break;
          case CTRL_EDITBOX:
	    {
                GtkRequisition req;

		if (ctrl->editbox.has_list) {
		    w = gtk_combo_new();
		    gtk_combo_set_value_in_list(GTK_COMBO(w), FALSE, TRUE);
		    uc->entry = GTK_COMBO(w)->entry;
		    uc->list = GTK_COMBO(w)->list;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -