📄 gtkdlg.c
字号:
dp->data, EVENT_REFRESH); } }}void dlg_coloursel_start(union control *ctrl, void *dlg, int r, int g, int b){ struct dlgparam *dp = (struct dlgparam *)dlg; struct uctrl *uc = dlg_find_byctrl(dp, ctrl); gdouble cvals[4]; GtkWidget *coloursel = gtk_color_selection_dialog_new("Select a colour"); GtkColorSelectionDialog *ccs = GTK_COLOR_SELECTION_DIALOG(coloursel); dp->coloursel_result.ok = FALSE; gtk_window_set_modal(GTK_WINDOW(coloursel), TRUE); gtk_color_selection_set_opacity(GTK_COLOR_SELECTION(ccs->colorsel), FALSE); cvals[0] = r / 255.0; cvals[1] = g / 255.0; cvals[2] = b / 255.0; cvals[3] = 1.0; /* fully opaque! */ gtk_color_selection_set_color(GTK_COLOR_SELECTION(ccs->colorsel), cvals); gtk_object_set_data(GTK_OBJECT(ccs->ok_button), "user-data", (gpointer)coloursel); gtk_object_set_data(GTK_OBJECT(ccs->cancel_button), "user-data", (gpointer)coloursel); gtk_object_set_data(GTK_OBJECT(coloursel), "user-data", (gpointer)uc); gtk_signal_connect(GTK_OBJECT(ccs->ok_button), "clicked", GTK_SIGNAL_FUNC(coloursel_ok), (gpointer)dp); gtk_signal_connect(GTK_OBJECT(ccs->cancel_button), "clicked", GTK_SIGNAL_FUNC(coloursel_cancel), (gpointer)dp); gtk_signal_connect_object(GTK_OBJECT(ccs->ok_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer)coloursel); gtk_signal_connect_object(GTK_OBJECT(ccs->cancel_button), "clicked", GTK_SIGNAL_FUNC(gtk_widget_destroy), (gpointer)coloursel); gtk_widget_show(coloursel);}int dlg_coloursel_results(union control *ctrl, void *dlg, int *r, int *g, int *b){ struct dlgparam *dp = (struct dlgparam *)dlg; if (dp->coloursel_result.ok) { *r = dp->coloursel_result.r; *g = dp->coloursel_result.g; *b = dp->coloursel_result.b; return 1; } else return 0;}/* ---------------------------------------------------------------------- * Signal handlers while the dialog box is active. */static gboolean widget_focus(GtkWidget *widget, GdkEventFocus *event, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; struct uctrl *uc = dlg_find_bywidget(dp, widget); union control *focus; if (uc && uc->ctrl) focus = uc->ctrl; else focus = NULL; if (focus != dp->currfocus) { dp->lastfocus = dp->currfocus; dp->currfocus = focus; } return FALSE;}static void button_clicked(GtkButton *button, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(button)); uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_ACTION);}static void button_toggled(GtkToggleButton *tb, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(tb)); uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_VALCHANGE);}static int editbox_key(GtkWidget *widget, GdkEventKey *event, gpointer data){ /* * GtkEntry has a nasty habit of eating the Return key, which * is unhelpful since it doesn't actually _do_ anything with it * (it calls gtk_widget_activate, but our edit boxes never need * activating). So I catch Return before GtkEntry sees it, and * pass it straight on to the parent widget. Effect: hitting * Return in an edit box will now activate the default button * in the dialog just like it will everywhere else. */ if (event->keyval == GDK_Return && widget->parent != NULL) { gint return_val; gtk_signal_emit_stop_by_name(GTK_OBJECT(widget), "key_press_event"); gtk_signal_emit_by_name(GTK_OBJECT(widget->parent), "key_press_event", event, &return_val); return return_val; } return FALSE;}static void editbox_changed(GtkEditable *ed, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; if (!(dp->flags & FLAG_UPDATING_COMBO_LIST)) { struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(ed)); uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_VALCHANGE); }}static void editbox_lostfocus(GtkWidget *ed, GdkEventFocus *event, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(ed)); uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_REFRESH);}static int listitem_key(GtkWidget *item, GdkEventKey *event, gpointer data, int multiple){ GtkAdjustment *adj = GTK_ADJUSTMENT(data); if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up || event->keyval == GDK_Down || event->keyval == GDK_KP_Down || event->keyval == GDK_Page_Up || event->keyval == GDK_KP_Page_Up || event->keyval == GDK_Page_Down || event->keyval == GDK_KP_Page_Down) { /* * Up, Down, PgUp or PgDn have been pressed on a ListItem * in a list box. So, if the list box is single-selection: * * - if the list item in question isn't already selected, * we simply select it. * - otherwise, we find the next one (or next * however-far-away) in whichever direction we're going, * and select that. * + in this case, we must also fiddle with the * scrollbar to ensure the newly selected item is * actually visible. * * If it's multiple-selection, we do all of the above * except actually selecting anything, so we move the focus * and fiddle the scrollbar to follow it. */ GtkWidget *list = item->parent; gtk_signal_emit_stop_by_name(GTK_OBJECT(item), "key_press_event"); if (!multiple && GTK_WIDGET_STATE(item) != GTK_STATE_SELECTED) { gtk_list_select_child(GTK_LIST(list), item); } else { int direction = (event->keyval==GDK_Up || event->keyval==GDK_KP_Up || event->keyval==GDK_Page_Up || event->keyval==GDK_KP_Page_Up) ? -1 : +1; int step = (event->keyval==GDK_Page_Down || event->keyval==GDK_KP_Page_Down || event->keyval==GDK_Page_Up || event->keyval==GDK_KP_Page_Up) ? 2 : 1; int i, n; GList *children, *chead; chead = children = gtk_container_children(GTK_CONTAINER(list)); n = g_list_length(children); if (step == 2) { /* * Figure out how many list items to a screenful, * and adjust the step appropriately. */ step = 0.5 + adj->page_size * n / (adj->upper - adj->lower); step--; /* go by one less than that */ } i = 0; while (children != NULL) { if (item == children->data) break; children = children->next; i++; } while (step > 0) { if (direction < 0 && i > 0) children = children->prev, i--; else if (direction > 0 && i < n-1) children = children->next, i++; step--; } if (children && children->data) { if (!multiple) gtk_list_select_child(GTK_LIST(list), GTK_WIDGET(children->data)); gtk_widget_grab_focus(GTK_WIDGET(children->data)); gtk_adjustment_clamp_page (adj, adj->lower + (adj->upper-adj->lower) * i / n, adj->lower + (adj->upper-adj->lower) * (i+1) / n); } g_list_free(chead); } return TRUE; } return FALSE;}static int listitem_single_key(GtkWidget *item, GdkEventKey *event, gpointer data){ return listitem_key(item, event, data, FALSE);}static int listitem_multi_key(GtkWidget *item, GdkEventKey *event, gpointer data){ return listitem_key(item, event, data, TRUE);}static int listitem_button(GtkWidget *item, GdkEventButton *event, gpointer data){ struct dlgparam *dp = (struct dlgparam *)data; if (event->type == GDK_2BUTTON_PRESS || event->type == GDK_3BUTTON_PRESS) { struct uctrl *uc = dlg_find_bywidget(dp, GTK_WIDGET(item)); uc->ctrl->generic.handler(uc->ctrl, dp, dp->data, EVENT_ACTION); return TRUE; } 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)) { /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -