⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gtkdlg.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 5 页
字号:
                    /*                     * GTK doesn't appear to make it easy to                     * implement a proper draggable list; so                     * instead I'm just going to have to put an Up                     * and a Down button to the right of the actual                     * list box. Ah well.                     */                    GtkWidget *cols, *button;                    static const gint percentages[2] = { 80, 20 };                    cols = columns_new(4);                    columns_set_cols(COLUMNS(cols), 2, percentages);                    columns_add(COLUMNS(cols), w, 0, 1);                    gtk_widget_show(w);                    button = gtk_button_new_with_label("Up");                    columns_add(COLUMNS(cols), button, 1, 1);                    gtk_widget_show(button);		    gtk_signal_connect(GTK_OBJECT(button), "clicked",				       GTK_SIGNAL_FUNC(draglist_up), dp);                    gtk_signal_connect(GTK_OBJECT(button), "focus_in_event",                                       GTK_SIGNAL_FUNC(widget_focus), dp);                    button = gtk_button_new_with_label("Down");                    columns_add(COLUMNS(cols), button, 1, 1);                    gtk_widget_show(button);		    gtk_signal_connect(GTK_OBJECT(button), "clicked",				       GTK_SIGNAL_FUNC(draglist_down), dp);                    gtk_signal_connect(GTK_OBJECT(button), "focus_in_event",                                       GTK_SIGNAL_FUNC(widget_focus), dp);                    w = cols;                }            }            if (ctrl->generic.label) {                GtkWidget *label, *container;                label = gtk_label_new(ctrl->generic.label);		container = columns_new(4);                if (ctrl->listbox.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->listbox.percentwidth;                    percentages[0] = 100 - ctrl->listbox.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);                }                gtk_widget_show(label);                gtk_widget_show(w);		shortcut_add(scs, label, ctrl->listbox.shortcut,			     SHORTCUT_UCTRL, uc);                w = container;            }            break;          case CTRL_TEXT:	    /*	     * Wrapping text widgets don't sit well with the GTK	     * layout model, in which widgets state a minimum size	     * and the whole window then adjusts to the smallest	     * size it can sensibly take given its contents. A	     * wrapping text widget _has_ no clear minimum size;	     * instead it has a range of possibilities. It can be	     * one line deep but 2000 wide, or two lines deep and	     * 1000 pixels, or three by 867, or four by 500 and so	     * on. It can be as short as you like provided you	     * don't mind it being wide, or as narrow as you like	     * provided you don't mind it being tall.	     * 	     * Therefore, it fits very badly into the layout model.	     * Hence the only thing to do is pick a width and let	     * it choose its own number of lines. To do this I'm	     * going to cheat a little. All new wrapping text	     * widgets will be created with a minimal text content	     * "X"; then, after the rest of the dialog box is set	     * up and its size calculated, the text widgets will be	     * told their width and given their real text, which	     * will cause the size to be recomputed in the y	     * direction (because many of them will expand to more	     * than one line).	     */            uc->text = w = gtk_label_new("X");            gtk_misc_set_alignment(GTK_MISC(w), 0.0, 0.0);            gtk_label_set_line_wrap(GTK_LABEL(w), TRUE);	    uc->textsig =		gtk_signal_connect(GTK_OBJECT(w), "size-allocate",				   GTK_SIGNAL_FUNC(label_sizealloc), dp);            break;        }	assert(w != NULL);	columns_add(cols, w,		    COLUMN_START(ctrl->generic.column),		    COLUMN_SPAN(ctrl->generic.column));	if (left)	    columns_force_left_align(cols, w);	gtk_widget_show(w);	uc->toplevel = w;	dlg_add_uctrl(dp, uc);    }    return ret;}struct selparam {    struct dlgparam *dp;    Panels *panels;    GtkWidget *panel, *treeitem;    struct Shortcuts shortcuts;};static void treeitem_sel(GtkItem *item, gpointer data){    struct selparam *sp = (struct selparam *)data;    panels_switch_to(sp->panels, sp->panel);    sp->dp->shortcuts = &sp->shortcuts;    sp->dp->currtreeitem = sp->treeitem;}static void window_destroy(GtkWidget *widget, gpointer data){    gtk_main_quit();}static int tree_grab_focus(struct dlgparam *dp){    int i, f;    /*     * See if any of the treeitems has the focus.     */    f = -1;    for (i = 0; i < dp->ntreeitems; i++)        if (GTK_WIDGET_HAS_FOCUS(dp->treeitems[i])) {            f = i;            break;        }    if (f >= 0)        return FALSE;    else {        gtk_widget_grab_focus(dp->currtreeitem);        return TRUE;    }}gint tree_focus(GtkContainer *container, GtkDirectionType direction,                gpointer data){    struct dlgparam *dp = (struct dlgparam *)data;    gtk_signal_emit_stop_by_name(GTK_OBJECT(container), "focus");    /*     * If there's a focused treeitem, we return FALSE to cause the     * focus to move on to some totally other control. If not, we     * focus the selected one.     */    return tree_grab_focus(dp);}int win_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data){    struct dlgparam *dp = (struct dlgparam *)data;    if (event->keyval == GDK_Escape && dp->cancelbutton) {	gtk_signal_emit_by_name(GTK_OBJECT(dp->cancelbutton), "clicked");	return TRUE;    }    if ((event->state & GDK_MOD1_MASK) &&	(unsigned char)event->string[0] > 0 &&	(unsigned char)event->string[0] <= 127) {	int schr = (unsigned char)event->string[0];	struct Shortcut *sc = &dp->shortcuts->sc[schr];	switch (sc->action) {	  case SHORTCUT_TREE:	    tree_grab_focus(dp);	    break;	  case SHORTCUT_FOCUS:	    gtk_widget_grab_focus(sc->widget);	    break;	  case SHORTCUT_UCTRL:	    /*	     * We must do something sensible with a uctrl.	     * Precisely what this is depends on the type of	     * control.	     */	    switch (sc->uc->ctrl->generic.type) {	      case CTRL_CHECKBOX:	      case CTRL_BUTTON:		/* Check boxes and buttons get the focus _and_ get toggled. */		gtk_widget_grab_focus(sc->uc->toplevel);		gtk_signal_emit_by_name(GTK_OBJECT(sc->uc->toplevel),					"clicked");		break;	      case CTRL_FILESELECT:	      case CTRL_FONTSELECT:		/* File/font selectors have their buttons pressed (ooer),		 * and focus transferred to the edit box. */		gtk_signal_emit_by_name(GTK_OBJECT(sc->uc->button),					"clicked");		gtk_widget_grab_focus(sc->uc->entry);		break;	      case CTRL_RADIO:		/*		 * Radio buttons are fun, because they have		 * multiple shortcuts. We must find whether the		 * activated shortcut is the shortcut for the whole		 * group, or for a particular button. In the former		 * case, we find the currently selected button and		 * focus it; in the latter, we focus-and-click the		 * button whose shortcut was pressed.		 */		if (schr == sc->uc->ctrl->radio.shortcut) {		    int i;		    for (i = 0; i < sc->uc->ctrl->radio.nbuttons; i++)			if (gtk_toggle_button_get_active			    (GTK_TOGGLE_BUTTON(sc->uc->buttons[i]))) {			    gtk_widget_grab_focus(sc->uc->buttons[i]);			}		} else if (sc->uc->ctrl->radio.shortcuts) {		    int i;		    for (i = 0; i < sc->uc->ctrl->radio.nbuttons; i++)			if (schr == sc->uc->ctrl->radio.shortcuts[i]) {			    gtk_widget_grab_focus(sc->uc->buttons[i]);			    gtk_signal_emit_by_name				(GTK_OBJECT(sc->uc->buttons[i]), "clicked");			}		}		break;	      case CTRL_LISTBOX:		/*		 * If the list is really an option menu, we focus		 * and click it. Otherwise we tell it to focus one		 * of its children, which appears to do the Right		 * Thing.		 */		if (sc->uc->optmenu) {		    GdkEventButton bev;		    gint returnval;		    gtk_widget_grab_focus(sc->uc->optmenu);		    /* Option menus don't work using the "clicked" signal.		     * We need to manufacture a button press event :-/ */		    bev.type = GDK_BUTTON_PRESS;		    bev.button = 1;		    gtk_signal_emit_by_name(GTK_OBJECT(sc->uc->optmenu),					    "button_press_event",					    &bev, &returnval);		} else {                    assert(sc->uc->list != NULL);                    gtk_container_focus(GTK_CONTAINER(sc->uc->list),                                        GTK_DIR_TAB_FORWARD);		}		break;	    }	    break;	}    }    return FALSE;}int tree_key_press(GtkWidget *widget, GdkEventKey *event, gpointer data){    struct dlgparam *dp = (struct dlgparam *)data;    if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up ||        event->keyval == GDK_Down || event->keyval == GDK_KP_Down) {        int dir, i, j = -1;        for (i = 0; i < dp->ntreeitems; i++)            if (widget == dp->treeitems[i])		break;	if (i < dp->ntreeitems) {	    if (event->keyval == GDK_Up || event->keyval == GDK_KP_Up)		dir = -1;	    else		dir = +1;	    while (1) {		i += dir;		if (i < 0 || i >= dp->ntreeitems)		    break;	       /* nothing in that dir to select */		/*		 * Determine if this tree item is visible.		 */		{		    GtkWidget *w = dp->treeitems[i];		    int vis = TRUE;		    while (w && (GTK_IS_TREE_ITEM(w) || GTK_IS_TREE(w))) {			if (!GTK_WIDGET_VISIBLE(w)) {			    vis = FALSE;			    break;			}			w = w->parent;		    }		    if (vis) {			j = i;	       /* got one */			break;		    }		}	    }	}        gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),                                     "key_press_event");        if (j >= 0) {            gtk_signal_emit_by_name(GTK_OBJECT(dp->treeitems[j]), "toggle");            gtk_widget_grab_focus(dp->treeitems[j]);        }        return TRUE;    }    /*     * It's nice for Left and Right to expand and collapse tree     * branches.     */    if (event->keyval == GDK_Left || event->keyval == GDK_KP_Left) {        gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),                                     "key_press_event");	gtk_tree_item_collapse(GTK_TREE_ITEM(widget));	return TRUE;    }    if (event->keyval == GDK_Right || event->keyval == GDK_KP_Right) {        gtk_signal_emit_stop_by_name(GTK_OBJECT(widget),                                     "key_press_event");	gtk_tree_item_expand(GTK_TREE_ITEM(widget));	return TRUE;    }    return FALSE;}void shortcut_add(struct Shortcuts *scs, GtkWidget *labelw,		  int chr, int action, void *ptr){    GtkLabel *label = GTK_LABEL(labelw);    gchar *currstr, *pattern;    int i;    if (chr == NO_SHORTCUT)	return;    chr = tolower((unsigned char)chr);    assert(scs->sc[chr].action == SHORTCUT_EMPTY);    scs->sc[chr].action = action;    if (action == SHORTCUT_FOCUS) {	scs->sc[chr].uc = NULL;	scs->sc[chr].widget = (GtkWidget *)ptr;    } else {	scs->sc[chr].widget = NULL;	scs->sc[chr].uc = (struct uctrl *)ptr;    }    gtk_label_get(label, &currstr);    for (i = 0; currstr[i]; i++)	if (tolower((unsigned char)currstr[i]) == chr) {	    GtkRequisition req;	    pattern = dupprintf("%*s_", i, "");	    gtk_widget_size_request(GTK_WIDGET(label), &req);	    gtk_label_set_pattern(label, pattern);	    gtk_widget_set_usize(GTK_WIDGET(label), -1, req.height);	    sfree(pattern);	    break;	}}int get_listitemheight(void){    GtkWidget *listitem = gtk_list_item_new_with_label("foo");    Gtk

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -