📄 gtkdlg.c
字号:
GtkWidget *listitem = gtk_list_item_new(); GtkWidget *cols = columns_new(10); gint *percents; int i, ncols; /* Count the tabs in the text, and hence determine # of columns. */ ncols = 1; for (i = 0; text[i]; i++) if (text[i] == '\t') ncols++; assert(ncols <= (uc->ctrl->listbox.ncols ? uc->ctrl->listbox.ncols : 1)); percents = snewn(ncols, gint); percents[ncols-1] = 100; for (i = 0; i < ncols-1; i++) { percents[i] = uc->ctrl->listbox.percentages[i]; percents[ncols-1] -= percents[i]; } columns_set_cols(COLUMNS(cols), ncols, percents); sfree(percents); for (i = 0; i < ncols; i++) { int len = strcspn(text, "\t"); char *dup = dupprintf("%.*s", len, text); GtkWidget *label; text += len; if (*text) text++; label = gtk_label_new(dup); sfree(dup); columns_add(COLUMNS(cols), label, i, 1); columns_force_left_align(COLUMNS(cols), label); gtk_widget_show(label); } gtk_container_add(GTK_CONTAINER(listitem), cols); gtk_widget_show(cols); gtk_container_add(GTK_CONTAINER(uc->list), listitem); gtk_widget_show(listitem); if (ctrl->listbox.multisel) { gtk_signal_connect(GTK_OBJECT(listitem), "key_press_event", GTK_SIGNAL_FUNC(listitem_multi_key), uc->adj); } else { gtk_signal_connect(GTK_OBJECT(listitem), "key_press_event", GTK_SIGNAL_FUNC(listitem_single_key), uc->adj); } gtk_signal_connect(GTK_OBJECT(listitem), "focus_in_event", GTK_SIGNAL_FUNC(widget_focus), dp); gtk_signal_connect(GTK_OBJECT(listitem), "button_press_event", GTK_SIGNAL_FUNC(listitem_button), dp); gtk_object_set_data(GTK_OBJECT(listitem), "user-data", GINT_TO_POINTER(id)); } else { /* * List item in a combo-box list, which means the sensible * thing to do is make it a perfectly normal label. Hence * tabs are disregarded. */ GtkWidget *listitem = gtk_list_item_new_with_label(text); gtk_container_add(GTK_CONTAINER(uc->list), listitem); gtk_widget_show(listitem); gtk_object_set_data(GTK_OBJECT(listitem), "user-data", GINT_TO_POINTER(id)); } dp->flags &= ~FLAG_UPDATING_COMBO_LIST;}int dlg_listbox_getid(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); GList *children; GtkObject *item; assert(uc->ctrl->generic.type == CTRL_EDITBOX || uc->ctrl->generic.type == CTRL_LISTBOX); assert(uc->menu != NULL || uc->list != NULL); children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu : uc->list)); item = GTK_OBJECT(g_list_nth_data(children, index)); g_list_free(children); return GPOINTER_TO_INT(gtk_object_get_data(GTK_OBJECT(item), "user-data"));}/* dlg_listbox_index returns <0 if no single element is selected. */int dlg_listbox_index(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); GList *children; GtkWidget *item, *activeitem; int i; int selected = -1; assert(uc->ctrl->generic.type == CTRL_EDITBOX || uc->ctrl->generic.type == CTRL_LISTBOX); assert(uc->menu != NULL || uc->list != NULL); if (uc->menu) activeitem = gtk_menu_get_active(GTK_MENU(uc->menu)); else activeitem = NULL; /* unnecessarily placate gcc */ children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu : uc->list)); for (i = 0; children!=NULL && (item = GTK_WIDGET(children->data))!=NULL; i++, children = children->next) { if (uc->menu ? activeitem == item : GTK_WIDGET_STATE(item) == GTK_STATE_SELECTED) { if (selected == -1) selected = i; else selected = -2; } } g_list_free(children); return selected < 0 ? -1 : selected;}int dlg_listbox_issel(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); GList *children; GtkWidget *item, *activeitem; assert(uc->ctrl->generic.type == CTRL_EDITBOX || uc->ctrl->generic.type == CTRL_LISTBOX); assert(uc->menu != NULL || uc->list != NULL); children = gtk_container_children(GTK_CONTAINER(uc->menu ? uc->menu : uc->list)); item = GTK_WIDGET(g_list_nth_data(children, index)); g_list_free(children); if (uc->menu) { activeitem = gtk_menu_get_active(GTK_MENU(uc->menu)); return item == activeitem; } else { return GTK_WIDGET_STATE(item) == GTK_STATE_SELECTED; }}void dlg_listbox_select(union control *ctrl, void *dlg, int index){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_EDITBOX || uc->ctrl->generic.type == CTRL_LISTBOX); assert(uc->optmenu != NULL || uc->list != NULL); if (uc->optmenu) { gtk_option_menu_set_history(GTK_OPTION_MENU(uc->optmenu), index); } else { gtk_list_select_item(GTK_LIST(uc->list), index); }}void dlg_text_set(union control *ctrl, void *dlg, char const *text){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_TEXT); assert(uc->text != NULL); gtk_label_set_text(GTK_LABEL(uc->text), text);}void dlg_filesel_set(union control *ctrl, void *dlg, Filename fn){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FILESELECT); assert(uc->entry != NULL); gtk_entry_set_text(GTK_ENTRY(uc->entry), fn.path);}void dlg_filesel_get(union control *ctrl, void *dlg, Filename *fn){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FILESELECT); assert(uc->entry != NULL); strncpy(fn->path, gtk_entry_get_text(GTK_ENTRY(uc->entry)), lenof(fn->path)); fn->path[lenof(fn->path)-1] = '\0';}void dlg_fontsel_set(union control *ctrl, void *dlg, FontSpec fs){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FONTSELECT); assert(uc->entry != NULL); gtk_entry_set_text(GTK_ENTRY(uc->entry), fs.name);}void dlg_fontsel_get(union control *ctrl, void *dlg, FontSpec *fs){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); assert(uc->ctrl->generic.type == CTRL_FONTSELECT); assert(uc->entry != NULL); strncpy(fs->name, gtk_entry_get_text(GTK_ENTRY(uc->entry)), lenof(fs->name)); fs->name[lenof(fs->name)-1] = '\0';}/* * Bracketing a large set of updates in these two functions will * cause the front end (if possible) to delay updating the screen * until it's all complete, thus avoiding flicker. */void dlg_update_start(union control *ctrl, void *dlg){ /* * Apparently we can't do this at all in GTK. GtkCList supports * freeze and thaw, but not GtkList. Bah. */}void dlg_update_done(union control *ctrl, void *dlg){ /* * Apparently we can't do this at all in GTK. GtkCList supports * freeze and thaw, but not GtkList. Bah. */}void dlg_set_focus(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); switch (ctrl->generic.type) { case CTRL_CHECKBOX: case CTRL_BUTTON: /* Check boxes and buttons get the focus _and_ get toggled. */ gtk_widget_grab_focus(uc->toplevel); break; case CTRL_FILESELECT: case CTRL_FONTSELECT: case CTRL_EDITBOX: /* Anything containing an edit box gets that focused. */ gtk_widget_grab_focus(uc->entry); break; case CTRL_RADIO: /* * Radio buttons: we find the currently selected button and * focus it. */ { int i; for (i = 0; i < ctrl->radio.nbuttons; i++) if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(uc->buttons[i]))) { gtk_widget_grab_focus(uc->buttons[i]); } } break; case CTRL_LISTBOX: /* * If the list is really an option menu, we focus it. * Otherwise we tell it to focus one of its children, which * appears to do the Right Thing. */ if (uc->optmenu) { gtk_widget_grab_focus(uc->optmenu); } else { assert(uc->list != NULL); gtk_container_focus(GTK_CONTAINER(uc->list), GTK_DIR_TAB_FORWARD); } break; }}/* * During event processing, you might well want to give an error * indication to the user. dlg_beep() is a quick and easy generic * error; dlg_error() puts up a message-box or equivalent. */void dlg_beep(void *dlg){ gdk_beep();}static void errmsg_button_clicked(GtkButton *button, gpointer data){ gtk_widget_destroy(GTK_WIDGET(data));}static void set_transient_window_pos(GtkWidget *parent, GtkWidget *child){ gint x, y, w, h, dx, dy; GtkRequisition req; gtk_window_set_position(GTK_WINDOW(child), GTK_WIN_POS_NONE); gtk_widget_size_request(GTK_WIDGET(child), &req); gdk_window_get_origin(GTK_WIDGET(parent)->window, &x, &y); gdk_window_get_size(GTK_WIDGET(parent)->window, &w, &h); /* * One corner of the transient will be offset inwards, by 1/4 * of the parent window's size, from the corresponding corner * of the parent window. The corner will be chosen so as to * place the transient closer to the centre of the screen; this * should avoid transients going off the edge of the screen on * a regular basis. */ if (x + w/2 < gdk_screen_width() / 2) dx = x + w/4; /* work from left edges */ else dx = x + 3*w/4 - req.width; /* work from right edges */ if (y + h/2 < gdk_screen_height() / 2) dy = y + h/4; /* work from top edges */ else dy = y + 3*h/4 - req.height; /* work from bottom edges */ gtk_widget_set_uposition(GTK_WIDGET(child), dx, dy);}void dlg_error_msg(void *dlg, char *msg){ struct dlgparam *dp = (struct dlgparam *)dlg; GtkWidget *window, *hbox, *text, *ok; window = gtk_dialog_new(); text = gtk_label_new(msg); gtk_misc_set_alignment(GTK_MISC(text), 0.0, 0.0); hbox = gtk_hbox_new(FALSE, 0); gtk_box_pack_start(GTK_BOX(hbox), text, FALSE, FALSE, 20); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), hbox, FALSE, FALSE, 20); gtk_widget_show(text); gtk_widget_show(hbox); gtk_window_set_title(GTK_WINDOW(window), "Error"); gtk_label_set_line_wrap(GTK_LABEL(text), TRUE); ok = gtk_button_new_with_label("OK"); gtk_box_pack_end(GTK_BOX(GTK_DIALOG(window)->action_area), ok, FALSE, FALSE, 0); gtk_widget_show(ok); GTK_WIDGET_SET_FLAGS(ok, GTK_CAN_DEFAULT); gtk_window_set_default(GTK_WINDOW(window), ok); gtk_signal_connect(GTK_OBJECT(ok), "clicked", GTK_SIGNAL_FUNC(errmsg_button_clicked), window); gtk_signal_connect(GTK_OBJECT(window), "destroy", GTK_SIGNAL_FUNC(window_destroy), NULL); gtk_window_set_modal(GTK_WINDOW(window), TRUE); gtk_window_set_transient_for(GTK_WINDOW(window), GTK_WINDOW(dp->window)); set_transient_window_pos(dp->window, window); gtk_widget_show(window); gtk_main();}/* * This function signals to the front end that the dialog's * processing is completed, and passes an integer value (typically * a success status). */void dlg_end(void *dlg, int value){ struct dlgparam *dp = (struct dlgparam *)dlg; dp->retval = value; gtk_widget_destroy(dp->window);}void dlg_refresh(union control *ctrl, void *dlg){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc; if (ctrl) { if (ctrl->generic.handler != NULL) ctrl->generic.handler(ctrl, dp, dp->data, EVENT_REFRESH); } else { int i; for (i = 0; (uc = index234(dp->byctrl, i)) != NULL; i++) { assert(uc->ctrl != NULL); if (uc->ctrl->generic.handler != NULL) uc->ctrl->generic.handler(uc->ctrl, dp,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -