📄 gtkdlg.c
字号:
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 + -