Continuing work on the GTK config box. Created uxcfg.c for the
authorsimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 14 Mar 2003 18:35:01 +0000 (18:35 +0000)
committersimon <simon@cda61777-01e9-0310-a592-d414129be87e>
Fri, 14 Mar 2003 18:35:01 +0000 (18:35 +0000)
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
unix/gtkdlg.c
unix/unix.h
unix/uxcfg.c [new file with mode: 0644]
wincfg.c

index 6aac6ce..87bab60 100644 (file)
--- 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)));
index 85a2d7b..2b1f136 100644 (file)
@@ -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 <assert.h>
 #include <gtk/gtk.h>
 
@@ -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`
  */
 
index 01c7a9b..b003ac7 100644 (file)
@@ -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 (file)
index 0000000..6daa19b
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * uxcfg.c - the Unix-specific parts of the PuTTY configuration
+ * box.
+ */
+
+#include <assert.h>
+#include <stdlib.h>
+
+#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));
+}
index 5b5bf9a..38e36ab 100644 (file)
--- 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.
      */