Various cosmetic fixes to the GTK config box: vertical alignment of
[sgt/putty] / mac / macctrls.c
index 5903b55..5076595 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: macctrls.c,v 1.2 2003/03/18 00:35:40 ben Exp $ */
+/* $Id: macctrls.c,v 1.8 2003/03/21 00:24:17 ben Exp $ */
 /*
  * Copyright (c) 2003 Ben Harris
  * All rights reserved.
@@ -34,6 +34,9 @@
 #include <TextUtils.h>
 #include <Windows.h>
 
+#include <assert.h>
+#include <string.h>
+
 #include "putty.h"
 #include "mac.h"
 #include "macresid.h"
@@ -50,6 +53,8 @@ union macctrl {
        } type;
        /* Template from which this was generated */
        union control *ctrl;
+       /* Next control in this panel */
+       union macctrl *next;
     } generic;
     struct {
        struct macctrl_generic generic;
@@ -72,16 +77,21 @@ union macctrl {
 struct mac_layoutstate {
     Point pos;
     unsigned int width;
+    unsigned int panelnum;
 };
 
 #define ctrlevent(mcs, mc, event) do {                                 \
     if ((mc)->generic.ctrl->generic.handler != NULL)                   \
-       (*(mc)->generic.ctrl->generic.handler)((mc)->generic.ctrl, (mc),\
+       (*(mc)->generic.ctrl->generic.handler)((mc)->generic.ctrl, (mcs),\
                                               (mcs)->data, (event));   \
 } while (0)
 
+#define findbyctrl(mcs, ctrl)                                          \
+    find234((mcs)->byctrl, (ctrl), macctrl_cmp_byctrl_find)
+
 static void macctrl_layoutset(struct mac_layoutstate *, struct controlset *, 
                              WindowPtr, struct macctrls *);
+static void macctrl_switchtopanel(struct macctrls *, unsigned int);
 static void macctrl_text(struct macctrls *, WindowPtr,
                         struct mac_layoutstate *, union control *);
 static void macctrl_radio(struct macctrls *, WindowPtr,
@@ -93,6 +103,8 @@ static void macctrl_button(struct macctrls *, WindowPtr,
 #if !TARGET_API_MAC_CARBON
 static pascal SInt32 macctrl_sys7_text_cdef(SInt16, ControlRef,
                                            ControlDefProcMessage, SInt32);
+static pascal SInt32 macctrl_sys7_default_cdef(SInt16, ControlRef,
+                                              ControlDefProcMessage, SInt32);
 #endif
 
 #if !TARGET_API_MAC_CARBON
@@ -119,6 +131,8 @@ static void macctrl_init()
     if (inited) return;
     cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Text);
     (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_text_cdef);
+    cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Default);
+    (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_default_cdef);
     inited = 1;
 #endif
 }
@@ -137,6 +151,19 @@ static int macctrl_cmp_byctrl(void *av, void *bv)
        return 0;
 }
 
+static int macctrl_cmp_byctrl_find(void *av, void *bv)
+{
+    union control *a = (union control *)av;
+    union macctrl *b = (union macctrl *)bv;
+
+    if (a < b->generic.ctrl)
+       return -1;
+    else if (a > b->generic.ctrl)
+       return +1;
+    else
+       return 0;
+}
+
 void macctrl_layoutbox(struct controlbox *cb, WindowPtr window,
                       struct macctrls *mcs)
 {
@@ -152,13 +179,29 @@ void macctrl_layoutbox(struct controlbox *cb, WindowPtr window,
     rect = window->portRect;
 #endif
     curstate.pos.h = rect.left + 13;
-    curstate.pos.v = rect.top + 13;
+    curstate.pos.v = rect.bottom - 59;
     curstate.width = rect.right - rect.left - (13 * 2);
     if (mac_gestalts.apprvers >= 0x100)
        CreateRootControl(window, &root);
     mcs->byctrl = newtree234(macctrl_cmp_byctrl);
-    for (i = 0; i < cb->nctrlsets; i++)
+    /* Count the number of panels */
+    mcs->npanels = 1;
+    for (i = 1; i < cb->nctrlsets; i++)
+       if (strcmp(cb->ctrlsets[i]->pathname, cb->ctrlsets[i-1]->pathname))
+           mcs->npanels++;
+    mcs->panels = smalloc(sizeof(*mcs->panels) * mcs->npanels);
+    memset(mcs->panels, 0, sizeof(*mcs->panels) * mcs->npanels);
+    curstate.panelnum = 0;
+    for (i = 0; i < cb->nctrlsets; i++) {
+       if (i > 0 && strcmp(cb->ctrlsets[i]->pathname,
+                           cb->ctrlsets[i-1]->pathname)) {
+           curstate.pos.v = rect.top + 13;
+           curstate.panelnum++;
+           assert(curstate.panelnum < mcs->npanels);
+       }
        macctrl_layoutset(&curstate, cb->ctrlsets[i], window, mcs);
+    }
+    macctrl_switchtopanel(mcs, 1);
 }
 
 static void macctrl_layoutset(struct mac_layoutstate *curstate,
@@ -168,6 +211,7 @@ static void macctrl_layoutset(struct mac_layoutstate *curstate,
     unsigned int i;
 
     fprintf(stderr, "--- begin set ---\n");
+    fprintf(stderr, "pathname = %s\n", s->pathname);
     if (s->boxname && *s->boxname)
        fprintf(stderr, "boxname = %s\n", s->boxname);
     if (s->boxtitle)
@@ -210,6 +254,44 @@ static void macctrl_layoutset(struct mac_layoutstate *curstate,
     }
 }
 
+static void macctrl_switchtopanel(struct macctrls *mcs, unsigned int which)
+{
+    unsigned int i, j;
+    union macctrl *mc;
+
+    /* Panel 0 is special and always visible. */
+    for (i = 1; i < mcs->npanels; i++)
+       for (mc = mcs->panels[i]; mc != NULL; mc = mc->generic.next)
+           switch (mc->generic.type) {
+             case MACCTRL_TEXT:
+               if (i == which)
+                   ShowControl(mc->text.tbctrl);
+               else
+                   HideControl(mc->text.tbctrl);
+               break;
+             case MACCTRL_RADIO:
+               for (j = 0; j < mc->generic.ctrl->radio.nbuttons; j++)
+                   if (i == which)
+                       ShowControl(mc->radio.tbctrls[j]);
+                   else
+                       HideControl(mc->radio.tbctrls[j]);
+               break;
+             case MACCTRL_CHECKBOX:
+               if (i == which)
+                   ShowControl(mc->checkbox.tbctrl);
+               else
+                   HideControl(mc->checkbox.tbctrl);
+               break;
+             case MACCTRL_BUTTON:
+               if (i == which)
+                   ShowControl(mc->button.tbctrl);
+               else
+                   HideControl(mc->button.tbctrl);
+               break;
+
+           }
+}
+
 static void macctrl_text(struct macctrls *mcs, WindowPtr window,
                         struct mac_layoutstate *curstate,
                         union control *ctrl)
@@ -247,6 +329,8 @@ static void macctrl_text(struct macctrls *mcs, WindowPtr window,
                                     SYS7_TEXT_PROC, (long)mc);
     }
     add234(mcs->byctrl, mc);
+    mc->generic.next = mcs->panels[curstate->panelnum];
+    mcs->panels[curstate->panelnum] = mc;
 }
 
 #if !TARGET_API_MAC_CARBON
@@ -313,6 +397,8 @@ static void macctrl_radio(struct macctrls *mcs, WindowPtr window,
                                          0, 0, 1, radioButProc, (long)mc);
     }
     add234(mcs->byctrl, mc);
+    mc->generic.next = mcs->panels[curstate->panelnum];
+    mcs->panels[curstate->panelnum] = mc;
     ctrlevent(mcs, mc, EVENT_REFRESH);
 }
 
@@ -336,6 +422,8 @@ static void macctrl_checkbox(struct macctrls *mcs, WindowPtr window,
                                     checkBoxProc, (long)mc);
     add234(mcs->byctrl, mc);
     curstate->pos.v += 22;
+    mc->generic.next = mcs->panels[curstate->panelnum];
+    mcs->panels[curstate->panelnum] = mc;
     ctrlevent(mcs, mc, EVENT_REFRESH);
 }
 
@@ -365,11 +453,65 @@ static void macctrl_button(struct macctrls *mcs, WindowPtr window,
        SetControlData(mc->button.tbctrl, kControlEntireControl,
                       kControlPushButtonDefaultTag,
                       sizeof(isdefault), &isdefault);
+    } else if (ctrl->button.isdefault) {
+       InsetRect(&bounds, -4, -4);
+       NewControl(window, &bounds, title, TRUE, 0, 0, 1,
+                  SYS7_DEFAULT_PROC, (long)mc);
+    }
+    if (mac_gestalts.apprvers >= 0x110) {
+       Boolean iscancel = ctrl->button.iscancel;
+
+       SetControlData(mc->button.tbctrl, kControlEntireControl,
+                      kControlPushButtonCancelTag,
+                      sizeof(iscancel), &iscancel);
     }
     add234(mcs->byctrl, mc);
+    mc->generic.next = mcs->panels[curstate->panelnum];
+    mcs->panels[curstate->panelnum] = mc;
     curstate->pos.v += 26;
 }
 
+#if !TARGET_API_MAC_CARBON
+static pascal SInt32 macctrl_sys7_default_cdef(SInt16 variant,
+                                              ControlRef control,
+                                              ControlDefProcMessage msg,
+                                              SInt32 param)
+{
+    RgnHandle rgn;
+    Rect rect;
+    int oval;
+
+    switch (msg) {
+      case drawCntl:
+       if ((*control)->contrlVis) {
+           rect = (*control)->contrlRect;
+           PenNormal();
+           PenSize(3, 3);
+           oval = (rect.bottom - rect.top) / 2 + 2;
+           FrameRoundRect(&rect, oval, oval);
+       }
+       return 0;
+      case calcCRgns:
+       if (param & (1 << 31)) {
+           param &= ~(1 << 31);
+           goto calcthumbrgn;
+       }
+       /* FALLTHROUGH */
+      case calcCntlRgn:
+       rgn = (RgnHandle)param;
+       RectRgn(rgn, &(*control)->contrlRect);
+       return 0;
+      case calcThumbRgn:
+      calcthumbrgn:
+       rgn = (RgnHandle)param;
+       SetEmptyRgn(rgn);
+       return 0;
+    }
+
+    return 0;
+}
+#endif
+
 
 void macctrl_activate(WindowPtr window, EventRecord *event)
 {
@@ -499,12 +641,8 @@ void macctrl_close(WindowPtr window)
 
     freetree234(mcs->byctrl);
     mcs->byctrl = NULL;
-
-/* XXX
-    DisposeWindow(window);
-    if (s->window == NULL)
-       sfree(s);
-*/
+    sfree(mcs->panels);
+    mcs->panels = NULL;
 }
 
 void dlg_update_start(union control *ctrl, void *dlg)
@@ -529,7 +667,7 @@ void dlg_set_focus(union control *ctrl, void *dlg)
     }
 }
 
-union control *dlg_last_focused(void *dlg)
+union control *dlg_last_focused(union control *ctrl, void *dlg)
 {
 
     return NULL;
@@ -585,9 +723,11 @@ void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size)
 
 void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton)
 {
-    union macctrl *mc = dlg;
+    struct macctrls *mcs = dlg;
+    union macctrl *mc = findbyctrl(mcs, ctrl);
     int i;
 
+    assert(mc != NULL);
     for (i = 0; i < ctrl->radio.nbuttons; i++) {
        if (i == whichbutton)
            SetControlValue(mc->radio.tbctrls[i],
@@ -601,9 +741,11 @@ void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton)
 
 int dlg_radiobutton_get(union control *ctrl, void *dlg)
 {
-    union macctrl *mc = dlg;
+    struct macctrls *mcs = dlg;
+    union macctrl *mc = findbyctrl(mcs, ctrl);
     int i;
 
+    assert(mc != NULL);
     for (i = 0; i < ctrl->radio.nbuttons; i++) {
        if (GetControlValue(mc->radio.tbctrls[i])  ==
            kControlRadioButtonCheckedValue)
@@ -619,8 +761,10 @@ int dlg_radiobutton_get(union control *ctrl, void *dlg)
 
 void dlg_checkbox_set(union control *ctrl, void *dlg, int checked)
 {
-    union macctrl *mc = dlg;
+    struct macctrls *mcs = dlg;
+    union macctrl *mc = findbyctrl(mcs, ctrl);
 
+    assert(mc != NULL);
     SetControlValue(mc->checkbox.tbctrl,
                    checked ? kControlCheckBoxCheckedValue :
                              kControlCheckBoxUncheckedValue);
@@ -628,8 +772,10 @@ void dlg_checkbox_set(union control *ctrl, void *dlg, int checked)
 
 int dlg_checkbox_get(union control *ctrl, void *dlg)
 {
-    union macctrl *mc = dlg;
+    struct macctrls *mcs = dlg;
+    union macctrl *mc = findbyctrl(mcs, ctrl);
 
+    assert(mc != NULL);
     return GetControlValue(mc->checkbox.tbctrl);
 }
 
@@ -704,12 +850,19 @@ void dlg_listbox_select(union control *ctrl, void *dlg, int index)
 
 void dlg_text_set(union control *ctrl, void *dlg, char const *text)
 {
-    union macctrl *mc = dlg;
+    struct macctrls *mcs = dlg;
+    union macctrl *mc = findbyctrl(mcs, ctrl);
+    Str255 title;
 
+    assert(mc != NULL);
     if (mac_gestalts.apprvers >= 0x100)
        SetControlData(mc->text.tbctrl, kControlEntireControl,
                       kControlStaticTextTextTag,
                       strlen(ctrl->text.label), ctrl->text.label);
+    else {
+       c2pstrcpy(title, text);
+       SetControlTitle(mc->text.tbctrl, title);
+    }
 }