📄 gtkdlg.c
字号:
if (uc->menu) {
/*
* List item in a drop-down (but non-combo) list. Tabs are
* ignored; we just provide a standard menu item with the
* text.
*/
GtkWidget *menuitem = gtk_menu_item_new_with_label(text);
gtk_container_add(GTK_CONTAINER(uc->menu), menuitem);
gtk_widget_show(menuitem);
gtk_object_set_data(GTK_OBJECT(menuitem), "user-data",
GINT_TO_POINTER(id));
gtk_signal_connect(GTK_OBJECT(menuitem), "activate",
GTK_SIGNAL_FUNC(menuitem_activate), dp);
} else if (!uc->entry) {
/*
* List item in a non-combo-box list box. We make all of
* these Columns containing GtkLabels. This allows us to do
* the nasty force_left hack irrespective of whether there
* are tabs in the thing.
*/
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_press), dp);
gtk_signal_connect(GTK_OBJECT(listitem), "button_release_event",
GTK_SIGNAL_FUNC(listitem_button_release), 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 {
int nitems;
GList *items;
gdouble newtop, newbot;
gtk_list_select_item(GTK_LIST(uc->list), index);
/*
* Scroll the list box if necessary to ensure the newly
* selected item is visible.
*/
items = gtk_container_children(GTK_CONTAINER(uc->list));
nitems = g_list_length(items);
if (nitems > 0) {
int modified = FALSE;
g_list_free(items);
newtop = uc->adj->lower +
(uc->adj->upper - uc->adj->lower) * index / nitems;
newbot = uc->adj->lower +
(uc->adj->upper - uc->adj->lower) * (index+1) / nitems;
if (uc->adj->value > newtop) {
modified = TRUE;
uc->adj->value = newtop;
} else if (uc->adj->value < newbot - uc->adj->page_size) {
modified = TRUE;
uc->adj->value = newbot - uc->adj->page_size;
}
if (modified)
gtk_adjustment_value_changed(uc->adj);
}
}
}
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_label_change(union control *ctrl, void *dlg, char const *text)
{
struct dlgparam *dp = (struct dlgparam *)dlg;
struct uctrl *uc = dlg_find_byctrl(dp, ctrl);
switch (uc->ctrl->generic.type) {
case CTRL_BUTTON:
gtk_label_set_text(GTK_LABEL(uc->toplevel), text);
shortcut_highlight(uc->toplevel, ctrl->button.shortcut);
break;
case CTRL_CHECKBOX:
gtk_label_set_text(GTK_LABEL(uc->toplevel), text);
shortcut_highlight(uc->toplevel, ctrl->checkbox.shortcut);
break;
case CTRL_RADIO:
gtk_label_set_text(GTK_LABEL(uc->label), text);
shortcut_highlight(uc->label, ctrl->radio.shortcut);
break;
case CTRL_EDITBOX:
gtk_label_set_text(GTK_LABEL(uc->label), text);
shortcut_highlight(uc->label, ctrl->editbox.shortcut);
break;
case CTRL_FILESELECT:
gtk_label_set_text(GTK_LABEL(uc->label), text);
shortcut_highlight(uc->label, ctrl->fileselect.shortcut);
break;
case CTRL_FONTSELECT:
gtk_label_set_text(GTK_LABEL(uc->label), text);
shortcut_highlight(uc->label, ctrl->fontselect.shortcut);
break;
case CTRL_LISTBOX:
gtk_label_set_text(GTK_LABEL(uc->label), text);
shortcut_highlight(uc->label, ctrl->listbox.shortcut);
break;
default:
assert(!"This shouldn't happen");
break;
}
}
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);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -