From 1d0d4a3be9a1fdaf3b34ed1a6ad51e3407ea3091 Mon Sep 17 00:00:00 2001 From: simon Date: Fri, 14 Mar 2003 18:35:01 +0000 Subject: [PATCH] Continuing work on the GTK config box. Created uxcfg.c for the Unix-specific config items; moved a stray Windows-specific config item (scrollbar-in-fullscreen) out into wincfg.c to stop it appearing on Unix; continued updates to gtkdlg.c. I now believe the GTK config box looks basically correct (modulo minor cosmetic issues and keyboard accelerators). Next step, add the event handling so it's actually functional. git-svn-id: svn://svn.tartarus.org/sgt/putty@2933 cda61777-01e9-0310-a592-d414129be87e --- config.c | 4 -- unix/gtkdlg.c | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++--- unix/unix.h | 4 ++ unix/uxcfg.c | 114 ++++++++++++++++++++++++++++++++++++ wincfg.c | 35 +++++++++++ 5 files changed, 330 insertions(+), 12 deletions(-) create mode 100644 unix/uxcfg.c diff --git a/config.c b/config.c index 6aac6ceb..87bab603 100644 --- a/config.c +++ b/config.c @@ -986,10 +986,6 @@ void setup_config_box(struct controlbox *b, struct sesslist *sesslist, ctrl_checkbox(s, "Display scrollbar", 'd', HELPCTX(window_scrollback), dlg_stdcheckbox_handler, I(offsetof(Config,scrollbar))); - ctrl_checkbox(s, "Display scrollbar in full screen mode", 'i', - HELPCTX(window_scrollback), - dlg_stdcheckbox_handler, - I(offsetof(Config,scrollbar_in_fullscreen))); ctrl_checkbox(s, "Reset scrollback on keypress", 'k', HELPCTX(window_scrollback), dlg_stdcheckbox_handler, I(offsetof(Config,scroll_on_key))); diff --git a/unix/gtkdlg.c b/unix/gtkdlg.c index 85a2d7b7..2b1f1368 100644 --- a/unix/gtkdlg.c +++ b/unix/gtkdlg.c @@ -2,6 +2,23 @@ * gtkdlg.c - GTK implementation of the PuTTY configuration box. */ +/* + * TODO: + * + * - event handling, in general! + * + * - keyboard stuff + * + accelerators + * + tab order + * + default button + * + * - cosmetics: + * + can't we _somehow_ have less leading between radio buttons? + * + wrapping text widgets, the horror, the horror + * + labels and their associated edit boxes don't line up + * properly + */ + #include #include @@ -15,7 +32,6 @@ #include "putty.h" #include "dialog.h" - void *dlg_get_privdata(union control *ctrl, void *dlg) { return NULL; /* FIXME */ @@ -211,7 +227,7 @@ int dlg_coloursel_results(union control *ctrl, void *dlg, * definitely a GtkWidget and should probably be added to a * GtkVbox.) */ -GtkWidget *layout_ctrls(struct controlset *s) +GtkWidget *layout_ctrls(struct controlset *s, int listitemheight) { Columns *cols; GtkWidget *ret; @@ -353,10 +369,152 @@ GtkWidget *layout_ctrls(struct controlset *s) w = container; } break; + case CTRL_FILESELECT: + case CTRL_FONTSELECT: + { + GtkWidget *ww; + GtkRequisition req; + char *browsebtn = + (ctrl->generic.type == CTRL_FILESELECT ? + "Browse..." : "Change..."); + + gint percentages[] = { 75, 25 }; + w = columns_new(4); + columns_set_cols(COLUMNS(w), 2, percentages); + + if (ctrl->generic.label) { + ww = gtk_label_new(ctrl->generic.label); + columns_add(COLUMNS(w), ww, 0, 2); + columns_force_left_align(COLUMNS(w), ww); + gtk_widget_show(ww); + } + + ww = gtk_entry_new(); + gtk_widget_size_request(ww, &req); + gtk_widget_set_usize(ww, 10, req.height); + columns_add(COLUMNS(w), ww, 0, 1); + gtk_widget_show(ww); + + ww = gtk_button_new_with_label(browsebtn); + columns_add(COLUMNS(w), ww, 1, 1); + gtk_widget_show(ww); + } + break; + case CTRL_LISTBOX: + if (ctrl->listbox.height == 0) { + w = gtk_option_menu_new(); + } else { + GtkWidget *list; + list = gtk_list_new(); + gtk_list_set_selection_mode(GTK_LIST(list), + (ctrl->listbox.multisel ? + GTK_SELECTION_MULTIPLE : + GTK_SELECTION_SINGLE)); + w = gtk_scrolled_window_new(NULL, NULL); + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(w), + list); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(w), + GTK_POLICY_NEVER, + GTK_POLICY_AUTOMATIC); + gtk_widget_show(list); + + /* + * Adjust the height of the scrolled window to the + * minimum given by the height parameter. + * + * This piece of guesswork is a horrid hack based + * on looking inside the GTK 1.2 sources + * (specifically gtkviewport.c, which appears to be + * the widget which provides the border around the + * scrolling area). Anyone lets me know how I can + * do this in a way which isn't at risk from GTK + * upgrades, I'd be grateful. + */ + { + int edge = GTK_WIDGET(list)->style->klass->ythickness; + gtk_widget_set_usize(w, 10, + 2*edge + (ctrl->listbox.height * + listitemheight)); + } +#if 1 +/* here is an example of a percentage-based tabbed list item */ +{ int i; for (i=0; i<10; i++) { + GtkWidget *listitem = gtk_list_item_new(); + GtkWidget *cols = columns_new(4); + GtkWidget *label1 = gtk_label_new("left"); + GtkWidget *label2 = gtk_label_new("right"); + GList *itemlist; + static const gint percents[] = { 50, 50 }; + columns_set_cols(COLUMNS(cols), 2, percents); + columns_add(COLUMNS(cols), label1, 0, 1); + columns_force_left_align(COLUMNS(cols), label1); + columns_add(COLUMNS(cols), label2, 1, 1); + columns_force_left_align(COLUMNS(cols), label2); + gtk_widget_show(label1); + gtk_widget_show(label2); + gtk_widget_show(cols); + gtk_container_add(GTK_CONTAINER(listitem), cols); + itemlist = g_list_append(NULL, listitem); + gtk_list_append_items(GTK_LIST(list), itemlist); + gtk_widget_show(listitem); +} } +#endif + + if (ctrl->listbox.draglist) { + /* + * 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); + button = gtk_button_new_with_label("Down"); + columns_add(COLUMNS(cols), button, 1, 1); + gtk_widget_show(button); + + 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); + + w = container; + } + break; case CTRL_TEXT: w = gtk_label_new(ctrl->generic.label); gtk_label_set_line_wrap(GTK_LABEL(w), TRUE); - gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_FILL); + /* FIXME: deal with wrapping! */ break; } if (w) { @@ -391,7 +549,7 @@ void do_config_box(void) { GtkWidget *window, *hbox, *vbox, *cols, *label, *tree, *treescroll, *panels, *panelvbox; - int index, level; + int index, level, listitemheight; struct controlbox *ctrlbox; char *path; GtkTreeItem *treeitemlevels[8]; @@ -403,13 +561,22 @@ void do_config_box(void) do_defaults(NULL, &cfg); + { + GtkWidget *listitem = gtk_list_item_new_with_label("foo"); + GtkRequisition req; + gtk_widget_size_request(listitem, &req); + listitemheight = req.height; + gtk_widget_unref(listitem); + } + ctrlbox = ctrl_new_box(); setup_config_box(ctrlbox, NULL, FALSE, 0); + unix_setup_config_box(ctrlbox, FALSE); window = gtk_dialog_new(); - gtk_container_set_border_width(GTK_CONTAINER(GTK_DIALOG(window)->vbox), 4); hbox = gtk_hbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->vbox), hbox, TRUE, TRUE, 0); + gtk_container_set_border_width(GTK_CONTAINER(hbox), 10); gtk_widget_show(hbox); vbox = gtk_vbox_new(FALSE, 4); gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0); @@ -424,6 +591,7 @@ void do_config_box(void) treescroll = gtk_scrolled_window_new(NULL, NULL); tree = gtk_tree_new(); gtk_tree_set_view_mode(GTK_TREE(tree), GTK_TREE_VIEW_ITEM); + gtk_tree_set_selection_mode(GTK_TREE(tree), GTK_SELECTION_BROWSE); gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(treescroll), tree); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(treescroll), @@ -441,7 +609,7 @@ void do_config_box(void) level = 0; for (index = 0; index < ctrlbox->nctrlsets; index++) { struct controlset *s = ctrlbox->ctrlsets[index]; - GtkWidget *w = layout_ctrls(s); + GtkWidget *w = layout_ctrls(s, listitemheight); if (!*s->pathname) { gtk_box_pack_start(GTK_BOX(GTK_DIALOG(window)->action_area), @@ -515,6 +683,7 @@ void do_config_box(void) } gtk_box_pack_start(GTK_BOX(panelvbox), w, FALSE, FALSE, 0); + gtk_widget_show(w); } } @@ -544,8 +713,8 @@ void do_config_box(void) /* Compile command for testing: - gcc -o gtkdlg gtk{dlg,cols,panel}.c ../{config,dialog,settings}.c \ - ../{misc,tree234,be_none}.c ux{store,misc,print}.c \ +gcc -g -o gtkdlg gtk{dlg,cols,panel}.c ../{config,dialog,settings}.c \ + ../{misc,tree234,be_none}.c ux{store,misc,print,cfg}.c \ -I. -I.. -I../charset -DTESTMODE `gtk-config --cflags --libs` */ diff --git a/unix/unix.h b/unix/unix.h index 01c7a9ba..b003ac74 100644 --- a/unix/unix.h +++ b/unix/unix.h @@ -66,6 +66,10 @@ int select_result(int fd, int event); int first_socket(int *state, int *rwx); int next_socket(int *state, int *rwx); +/* uxcfg.c */ +struct controlbox; +void unix_setup_config_box(struct controlbox *b, int midsession); + /* * In the Unix Unicode layer, DEFAULT_CODEPAGE is a special value * which causes mb_to_wc and wc_to_mb to call _libc_ rather than diff --git a/unix/uxcfg.c b/unix/uxcfg.c new file mode 100644 index 00000000..6daa19bc --- /dev/null +++ b/unix/uxcfg.c @@ -0,0 +1,114 @@ +/* + * uxcfg.c - the Unix-specific parts of the PuTTY configuration + * box. + */ + +#include +#include + +#include "putty.h" +#include "dialog.h" +#include "storage.h" + +void unix_setup_config_box(struct controlbox *b, int midsession) +{ + struct controlset *s, *s2; + union control *c; + int i; + +#ifdef FIXME + if (!midsession) { + /* + * Add the About button to the standard panel. + */ + s = ctrl_getset(b, "", "", ""); + c = ctrl_pushbutton(s, "About", 'a', HELPCTX(no_help), + about_handler, P(hwndp)); + c->generic.column = 0; + } +#endif + + /* + * The Config structure contains two Unix-specific elements + * which are not configured in here: stamp_utmp and + * login_shell. This is because pterm does not put up a + * configuration box right at the start, which is the only time + * when these elements would be useful to configure. + */ + + /* + * GTK makes it rather easier to put the scrollbar on the left + * than Windows does! + */ + s = ctrl_getset(b, "Window", "scrollback", + "Control the scrollback in the window"); + ctrl_checkbox(s, "Scrollbar on left", 'l', + HELPCTX(no_help), + dlg_stdcheckbox_handler, + I(offsetof(Config,scrollbar_on_left))); + /* + * Really this wants to go just after `Display scrollbar'. See + * if we can find that control, and do some shuffling. + */ + for (i = 0; i < s->ncontrols; i++) { + c = s->ctrls[i]; + if (c->generic.type == CTRL_CHECKBOX && + c->generic.context.i == offsetof(Config,scrollbar)) { + /* + * Control i is the scrollbar checkbox. + * Control s->ncontrols-1 is the scrollbar-on-left one. + */ + if (i < s->ncontrols-2) { + c = s->ctrls[s->ncontrols-1]; + memmove(s->ctrls+i+2, s->ctrls+i+1, + (s->ncontrols-i-2)*sizeof(union control *)); + s->ctrls[i+1] = c; + } + break; + } + } + + /* + * X requires three more fonts: bold, wide, and wide-bold; also + * we need the fiddly shadow-bold-offset control. This would + * make the Window/Appearance panel rather unwieldy and large, + * so I think the sensible thing here is to _move_ this + * controlset into a separate Window/Fonts panel! + */ + s2 = ctrl_getset(b, "Window/Appearance", "font", + "Font settings"); + /* Remove this controlset from b. */ + for (i = 0; i < b->nctrlsets; i++) { + if (b->ctrlsets[i] == s2) { + memmove(b->ctrlsets+i, b->ctrlsets+i+1, + (b->nctrlsets-i-1) * sizeof(*b->ctrlsets)); + b->nctrlsets--; + break; + } + } + ctrl_settitle(b, "Window/Fonts", "Options controlling font usage"); + s = ctrl_getset(b, "Window/Fonts", "font", + "Fonts for displaying non-bold text"); + ctrl_fontsel(s, "Font used for ordinary text", 'w', + HELPCTX(no_help), + dlg_stdfontsel_handler, I(offsetof(Config,font))); + ctrl_fontsel(s, "Font used for wide (CJK) text", 'w', + HELPCTX(no_help), + dlg_stdfontsel_handler, I(offsetof(Config,widefont))); + s = ctrl_getset(b, "Window/Fonts", "fontbold", + "Fonts for displaying bolded text"); + ctrl_fontsel(s, "Font used for bolded text", 'b', + HELPCTX(no_help), + dlg_stdfontsel_handler, I(offsetof(Config,boldfont))); + ctrl_fontsel(s, "Font used for bold wide text", 'i', + HELPCTX(no_help), + dlg_stdfontsel_handler, I(offsetof(Config,wideboldfont))); + ctrl_text(s, "If you leave the bold font selectors blank, bold text" + " will be displayed by overprinting (\"shadow bold\"). Note" + " that this only applies if you have not requested bolding" + " to be done by changing the text colour.", + HELPCTX(no_help)); + ctrl_editbox(s, "Horizontal offset for shadow bold:", 'z', 20, + HELPCTX(no_help), dlg_stdeditbox_handler, + I(offsetof(Config,shadowboldoffset)), I(-1)); +} diff --git a/wincfg.c b/wincfg.c index 5b5bf9a4..38e36abc 100644 --- a/wincfg.c +++ b/wincfg.c @@ -54,6 +54,41 @@ void win_setup_config_box(struct controlbox *b, HWND *hwndp, int has_help, } /* + * Full-screen mode is a Windows peculiarity; hence + * scrollbar_in_fullscreen is as well. + */ + s = ctrl_getset(b, "Window", "scrollback", + "Control the scrollback in the window"); + ctrl_checkbox(s, "Display scrollbar in full screen mode", 'i', + HELPCTX(window_scrollback), + dlg_stdcheckbox_handler, + I(offsetof(Config,scrollbar_in_fullscreen))); + /* + * Really this wants to go just after `Display scrollbar'. See + * if we can find that control, and do some shuffling. + */ + { + int i; + for (i = 0; i < s->ncontrols; i++) { + c = s->ctrls[i]; + if (c->generic.type == CTRL_CHECKBOX && + c->generic.context.i == offsetof(Config,scrollbar)) { + /* + * Control i is the scrollbar checkbox. + * Control s->ncontrols-1 is the scrollbar-in-FS one. + */ + if (i < s->ncontrols-2) { + c = s->ctrls[s->ncontrols-1]; + memmove(s->ctrls+i+2, s->ctrls+i+1, + (s->ncontrols-i-2)*sizeof(union control *)); + s->ctrls[i+1] = c; + } + break; + } + } + } + + /* * Windows has the AltGr key, which has various Windows- * specific options. */ -- 2.11.0