📄 gtkdlg.c
字号:
* 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; 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); } 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; } else { w = gtk_entry_new(); if (ctrl->editbox.password) gtk_entry_set_visibility(GTK_ENTRY(w), FALSE); uc->entry = w; } gtk_signal_connect(GTK_OBJECT(uc->entry), "changed", GTK_SIGNAL_FUNC(editbox_changed), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "key_press_event", GTK_SIGNAL_FUNC(editbox_key), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); /* * Edit boxes, for some strange reason, have a minimum * width of 150 in GTK 1.2. We don't want this - we'd * rather the edit boxes acquired their natural width * from the column layout of the rest of the box. * * Also, while we're here, we'll squirrel away the * edit box height so we can use that to centre its * label vertically beside it. */ gtk_widget_size_request(w, &req); gtk_widget_set_usize(w, 10, req.height); if (ctrl->generic.label) { GtkWidget *label, *container; label = gtk_label_new(ctrl->generic.label); shortcut_add(scs, label, ctrl->editbox.shortcut, SHORTCUT_FOCUS, uc->entry); container = columns_new(4); if (ctrl->editbox.percentwidth == 100) { columns_add(COLUMNS(container), label, 0, 1); columns_force_left_align(COLUMNS(container), label); columns_add(COLUMNS(container), w, 0, 1); } else { gint percentages[2]; percentages[1] = ctrl->editbox.percentwidth; percentages[0] = 100 - ctrl->editbox.percentwidth; columns_set_cols(COLUMNS(container), 2, percentages); columns_add(COLUMNS(container), label, 0, 1); columns_force_left_align(COLUMNS(container), label); columns_add(COLUMNS(container), w, 1, 1); /* Centre the label vertically. */ gtk_widget_set_usize(label, -1, req.height); gtk_misc_set_alignment(GTK_MISC(label), 0.0, 0.5); } gtk_widget_show(label); gtk_widget_show(w); w = container; } gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_out_event", GTK_SIGNAL_FUNC(editbox_lostfocus), dp); } break; case CTRL_FILESELECT: case CTRL_FONTSELECT: { GtkWidget *ww; GtkRequisition req; char *browsebtn = (ctrl->generic.type == CTRL_FILESELECT ? "Browse..." : "Change..."); gint percentages[] = { 75, 25 }; w = columns_new(4); columns_set_cols(COLUMNS(w), 2, percentages); if (ctrl->generic.label) { ww = gtk_label_new(ctrl->generic.label); columns_add(COLUMNS(w), ww, 0, 2); columns_force_left_align(COLUMNS(w), ww); gtk_widget_show(ww); shortcut_add(scs, ww, (ctrl->generic.type == CTRL_FILESELECT ? ctrl->fileselect.shortcut : ctrl->fontselect.shortcut), SHORTCUT_UCTRL, uc); } uc->entry = ww = gtk_entry_new(); gtk_widget_size_request(ww, &req); gtk_widget_set_usize(ww, 10, req.height); columns_add(COLUMNS(w), ww, 0, 1); gtk_widget_show(ww); uc->button = ww = gtk_button_new_with_label(browsebtn); columns_add(COLUMNS(w), ww, 1, 1); gtk_widget_show(ww); gtk_signal_connect(GTK_OBJECT(uc->entry), "key_press_event", GTK_SIGNAL_FUNC(editbox_key), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "changed", GTK_SIGNAL_FUNC(editbox_changed), dp); gtk_signal_connect(GTK_OBJECT(uc->entry), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); gtk_signal_connect(GTK_OBJECT(uc->button), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); gtk_signal_connect(GTK_OBJECT(ww), "clicked", GTK_SIGNAL_FUNC(filefont_clicked), dp); } break; case CTRL_LISTBOX: if (ctrl->listbox.height == 0) { uc->optmenu = w = gtk_option_menu_new(); uc->menu = gtk_menu_new(); gtk_option_menu_set_menu(GTK_OPTION_MENU(w), uc->menu); gtk_object_set_data(GTK_OBJECT(uc->menu), "user-data", (gpointer)uc->optmenu); gtk_signal_connect(GTK_OBJECT(uc->optmenu), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); } else { uc->list = gtk_list_new(); if (ctrl->listbox.multisel == 2) { gtk_list_set_selection_mode(GTK_LIST(uc->list), GTK_SELECTION_EXTENDED); } else if (ctrl->listbox.multisel == 1) { gtk_list_set_selection_mode(GTK_LIST(uc->list), GTK_SELECTION_MULTIPLE); } else { gtk_list_set_selection_mode(GTK_LIST(uc->list), GTK_SELECTION_SINGLE); } w = gtk_scrolled_window_new(NULL, NULL); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(w), uc->list); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); uc->adj = gtk_scrolled_window_get_vadjustment (GTK_SCROLLED_WINDOW(w)); gtk_widget_show(uc->list); gtk_signal_connect(GTK_OBJECT(uc->list), "selection-changed", GTK_SIGNAL_FUNC(list_selchange), dp); gtk_signal_connect(GTK_OBJECT(uc->list), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); /* * Adjust the height of the scrolled window to the * minimum given by the height parameter. * * This piece of guesswork is a horrid hack based * on looking inside the GTK 1.2 sources * (specifically gtkviewport.c, which appears to be * the widget which provides the border around the * scrolling area). Anyone lets me know how I can * do this in a way which isn't at risk from GTK * upgrades, I'd be grateful. */ { int edge = GTK_WIDGET(uc->list)->style->klass->ythickness; gtk_widget_set_usize(w, 10, 2*edge + (ctrl->listbox.height * listitemheight)); } if (ctrl->listbox.draglist) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -