📄 macctrls.c
字号:
/* $Id: macctrls.c,v 1.1.1.1 2003/06/02 15:55:41 pekangas Exp $ *//* * Copyright (c) 2003 Ben Harris * All rights reserved. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation * files (the "Software"), to deal in the Software without * restriction, including without limitation the rights to use, * copy, modify, merge, publish, distribute, sublicense, and/or * sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following * conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */#include <MacTypes.h>#include <Appearance.h>#include <ColorPicker.h>#include <Controls.h>#include <ControlDefinitions.h>#include <Events.h>#include <Lists.h>#include <Menus.h>#include <Resources.h>#include <Script.h>#include <Sound.h>#include <TextEdit.h>#include <TextUtils.h>#include <ToolUtils.h>#include <Windows.h>#include <assert.h>#include <string.h>#include "putty.h"#include "mac.h"#include "macresid.h"#include "dialog.h"#include "tree234.h"/* Range of menu IDs for popup menus */#define MENU_MIN 1024#define MENU_MAX 2048union macctrl { struct macctrl_generic { enum { MACCTRL_TEXT, MACCTRL_EDITBOX, MACCTRL_RADIO, MACCTRL_CHECKBOX, MACCTRL_BUTTON, MACCTRL_LISTBOX, MACCTRL_POPUP } type; /* Template from which this was generated */ union control *ctrl; /* Next control in this panel */ union macctrl *next; void *privdata; int freeprivdata; } generic; struct { struct macctrl_generic generic; ControlRef tbctrl; } text; struct { struct macctrl_generic generic; ControlRef tbctrl; ControlRef tblabel; } editbox; struct { struct macctrl_generic generic; ControlRef *tbctrls; ControlRef tblabel; } radio; struct { struct macctrl_generic generic; ControlRef tbctrl; } checkbox; struct { struct macctrl_generic generic; ControlRef tbctrl; ControlRef tbring; } button; struct { struct macctrl_generic generic; ControlRef tbctrl; ListHandle list; unsigned int nids; int *ids; } listbox; struct { struct macctrl_generic generic; ControlRef tbctrl; MenuRef menu; int menuid; unsigned int nids; int *ids; } popup;};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, (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_hideshowpanel(struct macctrls *, unsigned int, int);static void macctrl_switchtopanel(struct macctrls *, unsigned int);static void macctrl_setfocus(struct macctrls *, union macctrl *);static void macctrl_text(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_editbox(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_radio(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_checkbox(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_button(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_listbox(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);static void macctrl_popup(struct macctrls *, WindowPtr, struct mac_layoutstate *, union control *);#if !TARGET_API_MAC_CARBONstatic pascal SInt32 macctrl_sys7_editbox_cdef(SInt16, ControlRef, ControlDefProcMessage, SInt32);static pascal SInt32 macctrl_sys7_default_cdef(SInt16, ControlRef, ControlDefProcMessage, SInt32);static pascal SInt32 macctrl_sys7_listbox_cdef(SInt16, ControlRef, ControlDefProcMessage, SInt32);#endif#if !TARGET_API_MAC_CARBON/* * This trick enables us to keep all the CDEF code in the main * application, which makes life easier. For details, see * <http://developer.apple.com/technotes/tn/tn2003.html#custom_code_base>. */#pragma options align=mac68ktypedef struct { short jmpabs; /* 4EF9 */ ControlDefUPP theUPP;} **PatchCDEF;#pragma options align=reset#endifstatic void macctrl_init(){#if !TARGET_API_MAC_CARBON static int inited = 0; PatchCDEF cdef; if (inited) return; cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_EditBox); (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_editbox_cdef); cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_Default); (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_default_cdef); cdef = (PatchCDEF)GetResource(kControlDefProcResourceType, CDEF_ListBox); (*cdef)->theUPP = NewControlDefProc(macctrl_sys7_listbox_cdef); inited = 1;#endif}static int macctrl_cmp_byctrl(void *av, void *bv){ union macctrl *a = (union macctrl *)av; union macctrl *b = (union macctrl *)bv; if (a->generic.ctrl < b->generic.ctrl) return -1; else if (a->generic.ctrl > b->generic.ctrl) return +1; else 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;}static union control panellist;static void panellist_handler(union control *ctrl, void *dlg, void *data, int event){ struct macctrls *mcs = dlg; /* XXX what if there's no selection? */ if (event == EVENT_SELCHANGE) macctrl_switchtopanel(mcs, dlg_listbox_index(ctrl, dlg) + 1);}void macctrl_layoutbox(struct controlbox *cb, WindowPtr window, struct macctrls *mcs){ int i; struct mac_layoutstate curstate; ControlRef root; Rect rect; macctrl_init(); if (mac_gestalts.apprvers >= 0x100) CreateRootControl(window, &root);#if TARGET_API_MAC_CARBON GetPortBounds(GetWindowPort(window), &rect);#else rect = window->portRect;#endif mcs->window = window; mcs->byctrl = newtree234(macctrl_cmp_byctrl); mcs->focus = NULL; mcs->defbutton = NULL; mcs->canbutton = NULL; /* 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 = snewn(mcs->npanels, union macctrl *); memset(mcs->panels, 0, sizeof(*mcs->panels) * mcs->npanels); curstate.panelnum = 0; curstate.pos.h = rect.left + 13; curstate.pos.v = rect.top + 13; curstate.width = 160; panellist.listbox.type = CTRL_LISTBOX; panellist.listbox.handler = &panellist_handler; panellist.listbox.height = 20; panellist.listbox.percentwidth = 100; macctrl_listbox(mcs, window, &curstate, &panellist); /* XXX Start with panel 1 active */ curstate.pos.h = rect.left + 13 + 160 + 13; curstate.pos.v = rect.bottom - 33; curstate.width = rect.right - (rect.left + 13 + 160) - (13 * 2); 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); dlg_listbox_add(&panellist, mcs, cb->ctrlsets[i]->pathname); } macctrl_layoutset(&curstate, cb->ctrlsets[i], window, mcs); } macctrl_switchtopanel(mcs, 1); macctrl_hideshowpanel(mcs, 0, TRUE); /* 14 = proxies, 19 = portfwd, 20 = SSH bugs */}#define MAXCOLS 16static void macctrl_layoutset(struct mac_layoutstate *curstate, struct controlset *s, WindowPtr window, struct macctrls *mcs){ unsigned int i, j, ncols, colstart, colspan; struct mac_layoutstate cols[MAXCOLS], pos; cols[0] = *curstate; ncols = 1; for (i = 0; i < s->ncontrols; i++) { union control *ctrl = s->ctrls[i]; colstart = COLUMN_START(ctrl->generic.column); colspan = COLUMN_SPAN(ctrl->generic.column); if (ctrl->generic.type == CTRL_COLUMNS) { if (ctrl->columns.ncols != 1) { ncols = ctrl->columns.ncols; assert(ncols <= MAXCOLS); for (j = 0; j < ncols; j++) { cols[j] = cols[0]; if (j > 0) cols[j].pos.h = cols[j-1].pos.h + cols[j-1].width + 6; if (j == ncols - 1) cols[j].width = curstate->width - (cols[j].pos.h - curstate->pos.h); else cols[j].width = (curstate->width + 6) * ctrl->columns.percentages[j] / 100 - 6; } } else { for (j = 0; j < ncols; j++) if (cols[j].pos.v > cols[0].pos.v) cols[0].pos.v = cols[j].pos.v; cols[0].width = curstate->width; ncols = 1; } } else { pos = cols[colstart]; pos.width = cols[colstart + colspan - 1].width + (cols[colstart + colspan - 1].pos.h - cols[colstart].pos.h); for (j = colstart; j < colstart + colspan; j++) if (pos.pos.v < cols[j].pos.v) pos.pos.v = cols[j].pos.v; switch (ctrl->generic.type) { case CTRL_TEXT: macctrl_text(mcs, window, &pos, ctrl); break; case CTRL_EDITBOX: macctrl_editbox(mcs, window, &pos, ctrl); break; case CTRL_RADIO: macctrl_radio(mcs, window, &pos, ctrl); break; case CTRL_CHECKBOX: macctrl_checkbox(mcs, window, &pos, ctrl); break; case CTRL_BUTTON: macctrl_button(mcs, window, &pos, ctrl); break; case CTRL_LISTBOX: if (ctrl->listbox.height == 0) macctrl_popup(mcs, window, &pos, ctrl); else macctrl_listbox(mcs, window, &pos, ctrl); break; } for (j = colstart; j < colstart + colspan; j++) cols[j].pos.v = pos.pos.v; } } for (j = 0; j < ncols; j++) if (cols[j].pos.v > curstate->pos.v) curstate->pos.v = cols[j].pos.v;}static void macctrl_hideshowpanel(struct macctrls *mcs, unsigned int panel, int showit){ union macctrl *mc; int j;#define hideshow(c) do { \ if (showit) ShowControl(c); else HideControl(c); \} while (0) for (mc = mcs->panels[panel]; mc != NULL; mc = mc->generic.next) {#if !TARGET_API_MAC_CARBON if (mcs->focus == mc) macctrl_setfocus(mcs, NULL);#endif switch (mc->generic.type) { case MACCTRL_TEXT: hideshow(mc->text.tbctrl); break; case MACCTRL_EDITBOX: hideshow(mc->editbox.tbctrl); if (mc->editbox.tblabel != NULL) hideshow(mc->editbox.tblabel); break; case MACCTRL_RADIO: for (j = 0; j < mc->generic.ctrl->radio.nbuttons; j++) hideshow(mc->radio.tbctrls[j]); if (mc->radio.tblabel != NULL) hideshow(mc->radio.tblabel); break; case MACCTRL_CHECKBOX: hideshow(mc->checkbox.tbctrl); break; case MACCTRL_BUTTON: hideshow(mc->button.tbctrl); if (mc->button.tbring != NULL) hideshow(mc->button.tbring); break; case MACCTRL_LISTBOX: hideshow(mc->listbox.tbctrl); /* * At least under Mac OS 8.1, hiding a list box * doesn't hide its scroll bars. */#if TARGET_API_MAC_CARBON hideshow(GetListVerticalScrollBar(mc->listbox.list));#else hideshow((*mc->listbox.list)->vScroll);#endif break; case MACCTRL_POPUP: hideshow(mc->popup.tbctrl); break; } }}static void macctrl_switchtopanel(struct macctrls *mcs, unsigned int which){ macctrl_hideshowpanel(mcs, mcs->curpanel, FALSE); macctrl_hideshowpanel(mcs, which, TRUE); mcs->curpanel = which;}#if !TARGET_API_MAC_CARBON/* * System 7 focus manipulation */static void macctrl_defocus(union macctrl *mc){ assert(mac_gestalts.apprvers < 0x100); switch (mc->generic.type) { case MACCTRL_EDITBOX: TEDeactivate((TEHandle)(*mc->editbox.tbctrl)->contrlData); break; }}static void macctrl_enfocus(union macctrl *mc){ assert(mac_gestalts.apprvers < 0x100); switch (mc->generic.type) { case MACCTRL_EDITBOX: TEActivate((TEHandle)(*mc->editbox.tbctrl)->contrlData); break; }}static void macctrl_setfocus(struct macctrls *mcs, union macctrl *mc){ if (mcs->focus == mc) return; if (mcs->focus != NULL) macctrl_defocus(mcs->focus); mcs->focus = mc; if (mc != NULL) macctrl_enfocus(mc);}#endifstatic void macctrl_text(struct macctrls *mcs, WindowPtr window, struct mac_layoutstate *curstate, union control *ctrl){ union macctrl *mc = snew(union macctrl); Rect bounds; SInt16 height; assert(ctrl->text.label != NULL); mc->generic.type = MACCTRL_TEXT; mc->generic.ctrl = ctrl; mc->generic.privdata = NULL; bounds.left = curstate->pos.h; bounds.right = bounds.left + curstate->width; bounds.top = curstate->pos.v; bounds.bottom = bounds.top + 16; if (mac_gestalts.apprvers >= 0x100) { Size olen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -