📄 macctrls.c
字号:
return 0; case calcThumbRgn: calcthumbrgn: rgn = (RgnHandle)param; SetEmptyRgn(rgn); return 0; } return 0;}#endifstatic void macctrl_popup(struct macctrls *mcs, WindowPtr window, struct mac_layoutstate *curstate, union control *ctrl){ union macctrl *mc = snew(union macctrl); Rect bounds; Str255 title; unsigned int labelwidth; static int nextmenuid = MENU_MIN; int menuid; MenuRef menu; /* * <http://developer.apple.com/qa/tb/tb42.html> explains how to * create a popup menu with dynamic content. */ assert(ctrl->listbox.height == 0); assert(!ctrl->listbox.draglist); assert(!ctrl->listbox.multisel); mc->generic.type = MACCTRL_POPUP; mc->generic.ctrl = ctrl; mc->generic.privdata = NULL; c2pstrcpy(title, ctrl->button.label == NULL ? "" : ctrl->button.label); /* Find a spare menu ID and create the menu */ while (GetMenuHandle(nextmenuid) != NULL) if (++nextmenuid >= MENU_MAX) nextmenuid = MENU_MIN; menuid = nextmenuid++; menu = NewMenu(menuid, "\pdummy"); if (menu == NULL) return; mc->popup.menu = menu; mc->popup.menuid = menuid; InsertMenu(menu, kInsertHierarchicalMenu); /* The menu starts off empty */ mc->popup.nids = 0; mc->popup.ids = NULL; bounds.left = curstate->pos.h; bounds.right = bounds.left + curstate->width; bounds.top = curstate->pos.v; bounds.bottom = bounds.top + 20; /* XXX handle percentwidth == 100 */ labelwidth = curstate->width * (100 - ctrl->listbox.percentwidth) / 100; mc->popup.tbctrl = NewControl(window, &bounds, title, FALSE, popupTitleLeftJust, menuid, labelwidth, popupMenuProc + popupFixedWidth, (long)mc); add234(mcs->byctrl, mc); curstate->pos.v += 26; mc->generic.next = mcs->panels[curstate->panelnum]; mcs->panels[curstate->panelnum] = mc; ctrlevent(mcs, mc, EVENT_REFRESH);}void macctrl_activate(WindowPtr window, EventRecord *event){ struct macctrls *mcs = mac_winctrls(window); Boolean active = (event->modifiers & activeFlag) != 0; GrafPtr saveport; int i, j; ControlPartCode state; union macctrl *mc; GetPort(&saveport); SetPort((GrafPtr)GetWindowPort(window)); if (mac_gestalts.apprvers >= 0x100) SetThemeWindowBackground(window, active ? kThemeBrushModelessDialogBackgroundActive : kThemeBrushModelessDialogBackgroundInactive, TRUE); state = active ? kControlNoPart : kControlInactivePart; for (i = 0; i <= mcs->curpanel; i += mcs->curpanel) for (mc = mcs->panels[i]; mc != NULL; mc = mc->generic.next) { switch (mc->generic.type) { case MACCTRL_TEXT: HiliteControl(mc->text.tbctrl, state); break; case MACCTRL_EDITBOX: HiliteControl(mc->editbox.tbctrl, state); if (mc->editbox.tblabel != NULL) HiliteControl(mc->editbox.tblabel, state); break; case MACCTRL_RADIO: for (j = 0; j < mc->generic.ctrl->radio.nbuttons; j++) HiliteControl(mc->radio.tbctrls[j], state); if (mc->radio.tblabel != NULL) HiliteControl(mc->radio.tblabel, state); break; case MACCTRL_CHECKBOX: HiliteControl(mc->checkbox.tbctrl, state); break; case MACCTRL_BUTTON: HiliteControl(mc->button.tbctrl, state); if (mc->button.tbring != NULL) HiliteControl(mc->button.tbring, state); break; case MACCTRL_LISTBOX: HiliteControl(mc->listbox.tbctrl, state); break; case MACCTRL_POPUP: HiliteControl(mc->popup.tbctrl, state); break; }#if !TARGET_API_MAC_CARBON if (mcs->focus == mc) { if (active) macctrl_enfocus(mc); else macctrl_defocus(mc); }#endif } SetPort(saveport);}void macctrl_click(WindowPtr window, EventRecord *event){ Point mouse; ControlHandle control, oldfocus; int part, trackresult; GrafPtr saveport; union macctrl *mc; struct macctrls *mcs = mac_winctrls(window); int i; UInt32 features; GetPort(&saveport); SetPort((GrafPtr)GetWindowPort(window)); mouse = event->where; GlobalToLocal(&mouse); part = FindControl(mouse, window, &control); if (control != NULL) {#if !TARGET_API_MAC_CARBON /* * Special magic for scroll bars in list boxes, whose refcon * is the list. */ if (part == kControlUpButtonPart || part == kControlDownButtonPart || part == kControlPageUpPart || part == kControlPageDownPart || part == kControlIndicatorPart) mc = (union macctrl *) (*(ListHandle)GetControlReference(control))->refCon; else#endif mc = (union macctrl *)GetControlReference(control); if (mac_gestalts.apprvers >= 0x100) { if (GetControlFeatures(control, &features) == noErr && (features & kControlSupportsFocus) && (features & kControlGetsFocusOnClick) && GetKeyboardFocus(window, &oldfocus) == noErr && control != oldfocus) SetKeyboardFocus(window, control, part); trackresult = HandleControlClick(control, mouse, event->modifiers, (ControlActionUPP)-1); } else {#if !TARGET_API_MAC_CARBON if (mc->generic.type == MACCTRL_EDITBOX && control == mc->editbox.tbctrl) { TEHandle te = (TEHandle)(*control)->contrlData; macctrl_setfocus(mcs, mc); TEClick(mouse, !!(event->modifiers & shiftKey), te); goto done; } if (mc->generic.type == MACCTRL_LISTBOX && (control == mc->listbox.tbctrl || control == (*mc->listbox.list)->vScroll)) { macctrl_setfocus(mcs, mc); if (LClick(mouse, event->modifiers, mc->listbox.list)) /* double-click */ ctrlevent(mcs, mc, EVENT_ACTION); else ctrlevent(mcs, mc, EVENT_SELCHANGE); goto done; }#endif trackresult = TrackControl(control, mouse, (ControlActionUPP)-1); } switch (mc->generic.type) { case MACCTRL_RADIO: if (trackresult != 0) { for (i = 0; i < mc->generic.ctrl->radio.nbuttons; i++) if (mc->radio.tbctrls[i] == control) SetControlValue(mc->radio.tbctrls[i], kControlRadioButtonCheckedValue); else SetControlValue(mc->radio.tbctrls[i], kControlRadioButtonUncheckedValue); ctrlevent(mcs, mc, EVENT_VALCHANGE); } break; case MACCTRL_CHECKBOX: if (trackresult != 0) { SetControlValue(control, !GetControlValue(control)); ctrlevent(mcs, mc, EVENT_VALCHANGE); } break; case MACCTRL_BUTTON: if (trackresult != 0) ctrlevent(mcs, mc, EVENT_ACTION); break; case MACCTRL_LISTBOX: /* FIXME spot double-click */ ctrlevent(mcs, mc, EVENT_SELCHANGE); break; case MACCTRL_POPUP: ctrlevent(mcs, mc, EVENT_SELCHANGE); break; } } done: SetPort(saveport);}void macctrl_key(WindowPtr window, EventRecord *event){ ControlRef control; struct macctrls *mcs = mac_winctrls(window); union macctrl *mc; unsigned long dummy; switch (event->message & charCodeMask) { case kEnterCharCode: case kReturnCharCode: if (mcs->defbutton != NULL) { assert(mcs->defbutton->generic.type == MACCTRL_BUTTON); HiliteControl(mcs->defbutton->button.tbctrl, kControlButtonPart); /* * I'd like to delay unhilighting the button until after * the event has been processed, but by them the entire * dialgue box might have been destroyed. */ Delay(6, &dummy); HiliteControl(mcs->defbutton->button.tbctrl, kControlNoPart); ctrlevent(mcs, mcs->defbutton, EVENT_ACTION); } return; case kEscapeCharCode: if (mcs->canbutton != NULL) { assert(mcs->canbutton->generic.type == MACCTRL_BUTTON); HiliteControl(mcs->canbutton->button.tbctrl, kControlButtonPart); Delay(6, &dummy); HiliteControl(mcs->defbutton->button.tbctrl, kControlNoPart); ctrlevent(mcs, mcs->canbutton, EVENT_ACTION); } return; } if (mac_gestalts.apprvers >= 0x100) { if (GetKeyboardFocus(window, &control) == noErr && control != NULL) { HandleControlKey(control, (event->message & keyCodeMask) >> 8, event->message & charCodeMask, event->modifiers); mc = (union macctrl *)GetControlReference(control); switch (mc->generic.type) { case MACCTRL_LISTBOX: ctrlevent(mcs, mc, EVENT_SELCHANGE); break; default: ctrlevent(mcs, mc, EVENT_VALCHANGE); break; } } }#if !TARGET_API_MAC_CARBON else { TEHandle te; if (mcs->focus != NULL) { mc = mcs->focus; switch (mc->generic.type) { case MACCTRL_EDITBOX: te = (TEHandle)(*mc->editbox.tbctrl)->contrlData; TEKey(event->message & charCodeMask, te); ctrlevent(mcs, mc, EVENT_VALCHANGE); break; } } }#endif}void macctrl_update(WindowPtr window){#if TARGET_API_MAC_CARBON RgnHandle visrgn;#endif Rect rect; GrafPtr saveport; BeginUpdate(window); GetPort(&saveport); SetPort((GrafPtr)GetWindowPort(window)); if (mac_gestalts.apprvers >= 0x101) {#if TARGET_API_MAC_CARBON GetPortBounds(GetWindowPort(window), &rect);#else rect = window->portRect;#endif InsetRect(&rect, -1, -1); DrawThemeModelessDialogFrame(&rect, mac_frontwindow() == window ? kThemeStateActive : kThemeStateInactive); }#if TARGET_API_MAC_CARBON visrgn = NewRgn(); GetPortVisibleRegion(GetWindowPort(window), visrgn); UpdateControls(window, visrgn); DisposeRgn(visrgn);#else UpdateControls(window, window->visRgn);#endif SetPort(saveport); EndUpdate(window);}#if TARGET_API_MAC_CARBON#define EnableItem EnableMenuItem#define DisableItem DisableMenuItem#endifvoid macctrl_adjustmenus(WindowPtr window){ MenuHandle menu; menu = GetMenuHandle(mFile); DisableItem(menu, iSave); /* XXX enable if modified */ EnableItem(menu, iSaveAs); EnableItem(menu, iDuplicate); menu = GetMenuHandle(mEdit); DisableItem(menu, 0);}void macctrl_close(WindowPtr window){ struct macctrls *mcs = mac_winctrls(window); union macctrl *mc; /* * Mostly, we don't bother disposing of the Toolbox controls, * since that will happen automatically when the window is * disposed of. Popup menus are an exception, because we have to * dispose of the menu ourselves, and doing that while the control * still holds a reference to it seems rude. */ while ((mc = index234(mcs->byctrl, 0)) != NULL) { if (mc->generic.privdata != NULL && mc->generic.freeprivdata) sfree(mc->generic.privdata); switch (mc->generic.type) { case MACCTRL_POPUP: DisposeControl(mc->popup.tbctrl); DeleteMenu(mc->popup.menuid); DisposeMenu(mc->popup.menu); break; } del234(mcs->byctrl, mc); sfree(mc); } freetree234(mcs->byctrl); mcs->byctrl = NULL; sfree(mcs->panels); mcs->panels = NULL;}void dlg_update_start(union control *ctrl, void *dlg){ /* No-op for now */}void dlg_update_done(union control *ctrl, void *dlg){ /* No-op for now */}void dlg_set_focus(union control *ctrl, void *dlg){ if (mac_gestalts.apprvers >= 0x100) { /* Use SetKeyboardFocus() */ } else { /* Do our own mucking around */ }}union control *dlg_last_focused(union control *ctrl, void *dlg){ return NULL;}void dlg_beep(void *dlg){ SysBeep(30);}void dlg_error_msg(void *dlg, char *msg){ Str255 pmsg; c2pstrcpy(pmsg, msg); ParamText(pmsg, NULL, NULL, NULL); StopAlert(128, NULL);}void dlg_end(void *dlg, int value){ struct macctrls *mcs = dlg; if (mcs->end != NULL) (*mcs->end)(mcs->window, value);};void dlg_refresh(union control *ctrl, void *dlg){ struct macctrls *mcs = dlg; union macctrl *mc; if (ctrl == NULL) return; /* FIXME */ mc = findbyctrl(mcs, ctrl); assert(mc != NULL); ctrlevent(mcs, mc, EVENT_REFRESH);};void *dlg_get_privdata(union control *ctrl, void *dlg){ struct macctrls *mcs = dlg; union macctrl *mc = findbyctrl(mcs, ctrl); assert(mc != NULL); return mc->generic.privdata;}void dlg_set_privdata(union control *ctrl, void *dlg, void *ptr){ struct macctrls *mcs = dlg; union macctrl *mc = findbyctrl(mcs, ctrl); assert(mc != NULL); mc->generic.privdata = ptr; mc->generic.freeprivdata = FALSE;}void *dlg_alloc_privdata(union control *ctrl, void *dlg, size_t size){ struct macctrls *mcs = dlg; union macctrl *mc = findbyctrl(mcs, ctrl); assert(mc != NULL); mc->generic.privdata = smalloc(size); mc->generic.freeprivdata = TRUE; return mc->generic.privdata;}/* * Radio Button control */void dlg_radiobutton_set(union control *ctrl, void *dlg, int whichbutton){ struct macctrls *mcs = dlg; union macctrl *mc = findbyctrl(mcs, ctrl); int i; if (mc == NULL) return; for (i = 0; i < ctrl->radio.nbuttons; i++) { if (i == whichbutton) SetControlValue(mc->radio.tbctrls[i], kControlRadioButtonCheckedValue); else SetControlValue(mc->radio.tbctrls[i], kControlRadioButtonUncheckedValue);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -