3 * Copyright (c) 2003 Ben Harris
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or
11 * sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 #include <Appearance.h>
30 #include <ColorPicker.h>
32 #include <ControlDefinitions.h>
36 #include <Resources.h>
40 #include <TextUtils.h>
41 #include <ToolUtils.h>
53 /* Range of menu IDs for popup menus */
59 struct macctrl_generic
{
70 /* Template from which this was generated */
72 /* Next control in this panel */
78 struct macctrl_generic generic
;
82 struct macctrl_generic generic
;
92 struct macctrl_generic generic
;
97 struct macctrl_generic generic
;
101 struct macctrl_generic generic
;
106 struct macctrl_generic generic
;
115 struct macctrl_generic generic
;
123 struct macctrl_generic generic
;
128 struct mac_layoutstate
{
133 unsigned int panelnum
;
136 #define ctrlevent(mcs, mc, event) do { \
137 if ((mc)->generic.ctrl->generic.handler != NULL) \
138 (*(mc)->generic.ctrl->generic.handler)((mc)->generic.ctrl, (mcs),\
139 (mcs)->data, (event)); \
142 #define findbyctrl(mcs, ctrl) \
143 find234((mcs)->byctrl, (ctrl), macctrl_cmp_byctrl_find)
145 static void macctrl_layoutset(struct mac_layoutstate
*, struct controlset
*,
146 WindowPtr
, struct macctrls
*);
147 static void macctrl_hideshowpanel(struct macctrls
*, unsigned int, int);
148 static void macctrl_switchtopanel(struct macctrls
*, unsigned int);
149 static void macctrl_setfocus(struct macctrls
*, union macctrl
*);
150 static void macctrl_text(struct macctrls
*, WindowPtr
,
151 struct mac_layoutstate
*, union control
*);
152 static void macctrl_editbox(struct macctrls
*, WindowPtr
,
153 struct mac_layoutstate
*, union control
*);
154 static void macctrl_radio(struct macctrls
*, WindowPtr
,
155 struct mac_layoutstate
*, union control
*);
156 static void macctrl_checkbox(struct macctrls
*, WindowPtr
,
157 struct mac_layoutstate
*, union control
*);
158 static void macctrl_button(struct macctrls
*, WindowPtr
,
159 struct mac_layoutstate
*, union control
*);
160 static void macctrl_listbox(struct macctrls
*, WindowPtr
,
161 struct mac_layoutstate
*, union control
*);
162 static void macctrl_popup(struct macctrls
*, WindowPtr
,
163 struct mac_layoutstate
*, union control
*);
164 static void macctrl_groupbox(struct macctrls
*, WindowPtr
,
165 struct mac_layoutstate
*, union control
*);
166 static void draglist_up(union macctrl
*, struct macctrls
*);
167 static void draglist_down(union macctrl
*, struct macctrls
*);
169 #if !TARGET_API_MAC_CARBON
170 static pascal SInt32
macctrl_sys7_editbox_cdef(SInt16
, ControlRef
,
171 ControlDefProcMessage
, SInt32
);
172 static pascal SInt32
macctrl_sys7_default_cdef(SInt16
, ControlRef
,
173 ControlDefProcMessage
, SInt32
);
174 static pascal SInt32
macctrl_sys7_listbox_cdef(SInt16
, ControlRef
,
175 ControlDefProcMessage
, SInt32
);
176 static pascal SInt32
macctrl_sys7_groupbox_cdef(SInt16
, ControlRef
,
177 ControlDefProcMessage
, SInt32
);
180 #if !TARGET_API_MAC_CARBON
182 * This trick enables us to keep all the CDEF code in the main
183 * application, which makes life easier. For details, see
184 * <http://developer.apple.com/technotes/tn/tn2003.html#custom_code_base>.
187 #pragma options align=mac68k
189 short jmpabs
; /* 4EF9 */
190 ControlDefUPP theUPP
;
192 #pragma options align=reset
195 static void macctrl_init()
197 #if !TARGET_API_MAC_CARBON
198 static int inited
= 0;
202 cdef
= (PatchCDEF
)GetResource(kControlDefProcResourceType
, CDEF_EditBox
);
203 (*cdef
)->theUPP
= NewControlDefProc(macctrl_sys7_editbox_cdef
);
204 cdef
= (PatchCDEF
)GetResource(kControlDefProcResourceType
, CDEF_Default
);
205 (*cdef
)->theUPP
= NewControlDefProc(macctrl_sys7_default_cdef
);
206 cdef
= (PatchCDEF
)GetResource(kControlDefProcResourceType
, CDEF_ListBox
);
207 (*cdef
)->theUPP
= NewControlDefProc(macctrl_sys7_listbox_cdef
);
208 cdef
= (PatchCDEF
)GetResource(kControlDefProcResourceType
, CDEF_GroupBox
);
209 (*cdef
)->theUPP
= NewControlDefProc(macctrl_sys7_groupbox_cdef
);
215 static int macctrl_cmp_byctrl(void *av
, void *bv
)
217 union macctrl
*a
= (union macctrl
*)av
;
218 union macctrl
*b
= (union macctrl
*)bv
;
220 if (a
->generic
.ctrl
< b
->generic
.ctrl
)
222 else if (a
->generic
.ctrl
> b
->generic
.ctrl
)
228 static int macctrl_cmp_byctrl_find(void *av
, void *bv
)
230 union control
*a
= (union control
*)av
;
231 union macctrl
*b
= (union macctrl
*)bv
;
233 if (a
< b
->generic
.ctrl
)
235 else if (a
> b
->generic
.ctrl
)
241 static union control panellist
;
243 static void panellist_handler(union control
*ctrl
, void *dlg
, void *data
,
246 struct macctrls
*mcs
= dlg
;
248 /* XXX what if there's no selection? */
249 if (event
== EVENT_SELCHANGE
)
250 macctrl_switchtopanel(mcs
, dlg_listbox_index(ctrl
, dlg
) + 1);
253 void macctrl_layoutbox(struct controlbox
*cb
, WindowPtr window
,
254 struct macctrls
*mcs
)
257 struct mac_layoutstate curstate
;
262 if (mac_gestalts
.apprvers
>= 0x100)
263 CreateRootControl(window
, &root
);
264 #if TARGET_API_MAC_CARBON
265 GetPortBounds(GetWindowPort(window
), &rect
);
267 rect
= window
->portRect
;
269 mcs
->window
= window
;
270 mcs
->byctrl
= newtree234(macctrl_cmp_byctrl
);
272 mcs
->defbutton
= NULL
;
273 mcs
->canbutton
= NULL
;
275 /* Count the number of panels */
277 for (i
= 1; i
< cb
->nctrlsets
; i
++)
278 if (strcmp(cb
->ctrlsets
[i
]->pathname
, cb
->ctrlsets
[i
-1]->pathname
))
280 mcs
->panels
= snewn(mcs
->npanels
, union macctrl
*);
281 memset(mcs
->panels
, 0, sizeof(*mcs
->panels
) * mcs
->npanels
);
282 curstate
.panelnum
= 0;
284 curstate
.pos
.h
= rect
.left
+ 13;
285 curstate
.pos
.v
= rect
.top
+ 13;
286 curstate
.width
= 160;
287 panellist
.listbox
.type
= CTRL_LISTBOX
;
288 panellist
.listbox
.handler
= &panellist_handler
;
289 panellist
.listbox
.height
= 20;
290 panellist
.listbox
.percentwidth
= 100;
291 macctrl_listbox(mcs
, window
, &curstate
, &panellist
);
292 /* XXX Start with panel 1 active */
294 curstate
.pos
.h
= rect
.left
+ 13 + 160 + 13;
295 curstate
.pos
.v
= rect
.bottom
- 33;
296 curstate
.width
= rect
.right
- (rect
.left
+ 13 + 160) - (13 * 2);
297 for (i
= 0; i
< cb
->nctrlsets
; i
++) {
298 if (i
> 0 && strcmp(cb
->ctrlsets
[i
]->pathname
,
299 cb
->ctrlsets
[i
-1]->pathname
)) {
300 curstate
.pos
.v
= rect
.top
+ 13;
302 assert(curstate
.panelnum
< mcs
->npanels
);
303 dlg_listbox_add(&panellist
, mcs
, cb
->ctrlsets
[i
]->pathname
);
305 macctrl_layoutset(&curstate
, cb
->ctrlsets
[i
], window
, mcs
);
307 macctrl_switchtopanel(mcs
, 1);
308 macctrl_hideshowpanel(mcs
, 0, TRUE
);
309 /* 14 = proxies, 19 = portfwd, 20 = SSH bugs */
316 static void macctrl_layoutset(struct mac_layoutstate
*curstate
,
317 struct controlset
*s
,
318 WindowPtr window
, struct macctrls
*mcs
)
320 unsigned int i
, j
, ncols
, colstart
, colspan
;
321 struct mac_layoutstate cols
[MAXCOLS
], pos
;
323 /* Start a containing box, if we have a boxname. */
324 if (s
->boxname
&& *s
->boxname
) {
325 curstate
->boxpos
= curstate
->pos
;
327 curstate
->boxname
= s
->boxtitle
;
328 curstate
->pos
.v
+= 10; /* XXX determine font height */
330 curstate
->boxname
= NULL
;
332 curstate
->pos
.v
+= 6;
333 curstate
->pos
.h
+= 12;
334 curstate
->width
-= 24;
337 /* Draw a title, if we have one. */
338 if (!s
->boxname
&& s
->boxtitle
) {
339 union control
*ctrl
= snew(union control
);
340 ctrl
->generic
.handler
= NULL
;
341 ctrl
->text
.label
= dupstr(s
->boxtitle
);
342 macctrl_text(mcs
, window
, curstate
, ctrl
);
343 /* FIXME: should be highlighted, centred or boxed */
349 for (i
= 0; i
< s
->ncontrols
; i
++) {
350 union control
*ctrl
= s
->ctrls
[i
];
352 colstart
= COLUMN_START(ctrl
->generic
.column
);
353 colspan
= COLUMN_SPAN(ctrl
->generic
.column
);
354 if (ctrl
->generic
.type
== CTRL_COLUMNS
) {
355 if (ctrl
->columns
.ncols
!= 1) {
356 ncols
= ctrl
->columns
.ncols
;
357 assert(ncols
<= MAXCOLS
);
358 for (j
= 0; j
< ncols
; j
++) {
361 cols
[j
].pos
.h
= cols
[j
-1].pos
.h
+ cols
[j
-1].width
+ 6;
363 cols
[j
].width
= curstate
->width
-
364 (cols
[j
].pos
.h
- curstate
->pos
.h
);
366 cols
[j
].width
= (curstate
->width
+ 6) *
367 ctrl
->columns
.percentages
[j
] / 100 - 6;
370 for (j
= 0; j
< ncols
; j
++)
371 if (cols
[j
].pos
.v
> cols
[0].pos
.v
)
372 cols
[0].pos
.v
= cols
[j
].pos
.v
;
373 cols
[0].width
= curstate
->width
;
377 pos
= cols
[colstart
];
378 pos
.width
= cols
[colstart
+ colspan
- 1].width
+
379 (cols
[colstart
+ colspan
- 1].pos
.h
- cols
[colstart
].pos
.h
);
381 for (j
= colstart
; j
< colstart
+ colspan
; j
++)
382 if (pos
.pos
.v
< cols
[j
].pos
.v
)
383 pos
.pos
.v
= cols
[j
].pos
.v
;
385 switch (ctrl
->generic
.type
) {
387 macctrl_text(mcs
, window
, &pos
, ctrl
);
390 macctrl_editbox(mcs
, window
, &pos
, ctrl
);
393 macctrl_radio(mcs
, window
, &pos
, ctrl
);
396 macctrl_checkbox(mcs
, window
, &pos
, ctrl
);
399 macctrl_button(mcs
, window
, &pos
, ctrl
);
402 if (ctrl
->listbox
.height
== 0)
403 macctrl_popup(mcs
, window
, &pos
, ctrl
);
405 macctrl_listbox(mcs
, window
, &pos
, ctrl
);
408 for (j
= colstart
; j
< colstart
+ colspan
; j
++)
409 cols
[j
].pos
.v
= pos
.pos
.v
;
412 for (j
= 0; j
< ncols
; j
++)
413 if (cols
[j
].pos
.v
> curstate
->pos
.v
)
414 curstate
->pos
.v
= cols
[j
].pos
.v
;
416 if (s
->boxname
&& *s
->boxname
) {
417 union control
*ctrl
= snew(union control
);
418 /* We're coming out of a box, so set the width back */
419 curstate
->pos
.h
-= 12;
420 curstate
->width
+= 24;
421 /* And draw the box to the original width */
422 macctrl_groupbox(mcs
, window
, curstate
, ctrl
);
426 static void macctrl_hideshowpanel(struct macctrls
*mcs
, unsigned int panel
,
432 #define hideshow(c) do { \
433 if (showit) ShowControl(c); else HideControl(c); \
436 for (mc
= mcs
->panels
[panel
]; mc
!= NULL
; mc
= mc
->generic
.next
) {
437 #if !TARGET_API_MAC_CARBON
438 if (mcs
->focus
== mc
)
439 macctrl_setfocus(mcs
, NULL
);
441 switch (mc
->generic
.type
) {
443 hideshow(mc
->text
.tbctrl
);
445 case MACCTRL_EDITBOX
:
446 hideshow(mc
->editbox
.tbctrl
);
447 if (mc
->editbox
.tblabel
!= NULL
)
448 hideshow(mc
->editbox
.tblabel
);
449 if (mc
->editbox
.tbbutton
!= NULL
)
450 hideshow(mc
->editbox
.tbbutton
);
453 for (j
= 0; j
< mc
->generic
.ctrl
->radio
.nbuttons
; j
++)
454 hideshow(mc
->radio
.tbctrls
[j
]);
455 if (mc
->radio
.tblabel
!= NULL
)
456 hideshow(mc
->radio
.tblabel
);
458 case MACCTRL_CHECKBOX
:
459 hideshow(mc
->checkbox
.tbctrl
);
462 hideshow(mc
->button
.tbctrl
);
463 if (mc
->button
.tbring
!= NULL
)
464 hideshow(mc
->button
.tbring
);
466 case MACCTRL_LISTBOX
:
467 hideshow(mc
->listbox
.tbctrl
);
468 if (mc
->listbox
.tbup
!= NULL
)
469 hideshow(mc
->listbox
.tbup
);
470 if (mc
->listbox
.tbdown
!= NULL
)
471 hideshow(mc
->listbox
.tbdown
);
473 * At least under Mac OS 8.1, hiding a list box
474 * doesn't hide its scroll bars.
476 #if TARGET_API_MAC_CARBON
477 hideshow(GetListVerticalScrollBar(mc
->listbox
.list
));
479 hideshow((*mc
->listbox
.list
)->vScroll
);
483 hideshow(mc
->popup
.tbctrl
);
485 case MACCTRL_GROUPBOX
:
486 hideshow(mc
->groupbox
.tbctrl
);
492 static void macctrl_switchtopanel(struct macctrls
*mcs
, unsigned int which
)
495 macctrl_hideshowpanel(mcs
, mcs
->curpanel
, FALSE
);
496 macctrl_hideshowpanel(mcs
, which
, TRUE
);
497 mcs
->curpanel
= which
;
500 #if !TARGET_API_MAC_CARBON
502 * System 7 focus manipulation
504 static void macctrl_defocus(union macctrl
*mc
)
507 assert(mac_gestalts
.apprvers
< 0x100);
508 switch (mc
->generic
.type
) {
509 case MACCTRL_EDITBOX
:
510 TEDeactivate((TEHandle
)(*mc
->editbox
.tbctrl
)->contrlData
);
515 static void macctrl_enfocus(union macctrl
*mc
)
518 assert(mac_gestalts
.apprvers
< 0x100);
519 switch (mc
->generic
.type
) {
520 case MACCTRL_EDITBOX
:
521 TEActivate((TEHandle
)(*mc
->editbox
.tbctrl
)->contrlData
);
526 static void macctrl_setfocus(struct macctrls
*mcs
, union macctrl
*mc
)
529 if (mcs
->focus
== mc
)
531 if (mcs
->focus
!= NULL
)
532 macctrl_defocus(mcs
->focus
);
539 static void macctrl_text(struct macctrls
*mcs
, WindowPtr window
,
540 struct mac_layoutstate
*curstate
,
543 union macctrl
*mc
= snew(union macctrl
);
547 assert(ctrl
->text
.label
!= NULL
);
548 mc
->generic
.type
= MACCTRL_TEXT
;
549 mc
->generic
.ctrl
= ctrl
;
550 mc
->generic
.privdata
= NULL
;
551 bounds
.left
= curstate
->pos
.h
;
552 bounds
.right
= bounds
.left
+ curstate
->width
;
553 bounds
.top
= curstate
->pos
.v
;
554 bounds
.bottom
= bounds
.top
+ 16;
555 if (mac_gestalts
.apprvers
>= 0x100) {
558 mc
->text
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
, 0, 0, 0,
559 kControlStaticTextProc
, (long)mc
);
560 SetControlData(mc
->text
.tbctrl
, kControlEntireControl
,
561 kControlStaticTextTextTag
,
562 strlen(ctrl
->text
.label
), ctrl
->text
.label
);
563 GetControlData(mc
->text
.tbctrl
, kControlEntireControl
,
564 kControlStaticTextTextHeightTag
,
565 sizeof(height
), &height
, &olen
);
567 #if !TARGET_API_MAC_CARBON
571 mc
->text
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
, 0, 0, 0,
572 SYS7_TEXT_PROC
, (long)mc
);
573 te
= (TEHandle
)(*mc
->text
.tbctrl
)->contrlData
;
574 TESetText(ctrl
->text
.label
, strlen(ctrl
->text
.label
), te
);
575 height
= TEGetHeight(1, (*te
)->nLines
, te
);
578 SizeControl(mc
->text
.tbctrl
, curstate
->width
, height
);
579 curstate
->pos
.v
+= height
+ 6;
580 add234(mcs
->byctrl
, mc
);
581 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
582 mcs
->panels
[curstate
->panelnum
] = mc
;
585 static void macctrl_editbox(struct macctrls
*mcs
, WindowPtr window
,
586 struct mac_layoutstate
*curstate
,
589 union macctrl
*mc
= snew(union macctrl
);
590 Rect lbounds
, bounds
, butbounds
;
591 static int nextmenuid
= MENU_MIN
;
595 mc
->generic
.type
= MACCTRL_EDITBOX
;
596 mc
->generic
.ctrl
= ctrl
;
597 mc
->generic
.privdata
= NULL
;
598 lbounds
.left
= curstate
->pos
.h
;
599 lbounds
.top
= curstate
->pos
.v
;
600 if (ctrl
->editbox
.percentwidth
== 100) {
601 if (ctrl
->editbox
.label
!= NULL
) {
602 lbounds
.right
= lbounds
.left
+ curstate
->width
;
603 lbounds
.bottom
= lbounds
.top
+ 16;
604 curstate
->pos
.v
+= 18;
606 bounds
.left
= curstate
->pos
.h
;
607 bounds
.right
= bounds
.left
+ curstate
->width
;
609 lbounds
.right
= lbounds
.left
+
610 curstate
->width
* (100 - ctrl
->editbox
.percentwidth
) / 100;
611 lbounds
.bottom
= lbounds
.top
+ 22;
612 bounds
.left
= lbounds
.right
;
613 bounds
.right
= lbounds
.left
+ curstate
->width
;
615 bounds
.top
= curstate
->pos
.v
;
616 bounds
.bottom
= bounds
.top
+ 22;
618 if (ctrl
->editbox
.has_list
) {
620 butbounds
.left
= butbounds
.right
- 20;
621 bounds
.right
-= 26; /* enough for 6 px gap and a button */
624 if (mac_gestalts
.apprvers
>= 0x100) {
625 if (ctrl
->editbox
.label
== NULL
)
626 mc
->editbox
.tblabel
= NULL
;
628 mc
->editbox
.tblabel
= NewControl(window
, &lbounds
, NULL
, FALSE
,
629 0, 0, 0, kControlStaticTextProc
,
631 SetControlData(mc
->editbox
.tblabel
, kControlEntireControl
,
632 kControlStaticTextTextTag
,
633 strlen(ctrl
->editbox
.label
), ctrl
->editbox
.label
);
635 InsetRect(&bounds
, 3, 3);
636 mc
->editbox
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
, 0, 0, 0,
637 ctrl
->editbox
.password ?
638 kControlEditTextPasswordProc
:
639 kControlEditTextProc
, (long)mc
);
641 #if !TARGET_API_MAC_CARBON
643 if (ctrl
->editbox
.label
== NULL
)
644 mc
->editbox
.tblabel
= NULL
;
646 mc
->editbox
.tblabel
= NewControl(window
, &lbounds
, NULL
, FALSE
,
647 0, 0, 0, SYS7_TEXT_PROC
,
649 TESetText(ctrl
->editbox
.label
, strlen(ctrl
->editbox
.label
),
650 (TEHandle
)(*mc
->editbox
.tblabel
)->contrlData
);
652 mc
->editbox
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
, 0, 0, 0,
653 SYS7_EDITBOX_PROC
, (long)mc
);
657 if (ctrl
->editbox
.has_list
) {
658 while (GetMenuHandle(nextmenuid
) != NULL
)
659 if (++nextmenuid
>= MENU_MAX
) nextmenuid
= MENU_MIN
;
660 menuid
= nextmenuid
++;
661 menu
= NewMenu(menuid
, "\pdummy");
662 if (menu
== NULL
) goto nomenu
;
663 mc
->editbox
.menu
= menu
;
664 mc
->editbox
.menuid
= menuid
;
665 InsertMenu(menu
, kInsertHierarchicalMenu
);
666 mc
->editbox
.nids
= 0;
667 mc
->editbox
.ids
= NULL
;
669 mc
->editbox
.tbbutton
= NewControl(window
, &butbounds
, NULL
, FALSE
,
670 popupTitleLeftJust
, menuid
, 0,
671 popupMenuProc
+ popupFixedWidth
,
677 curstate
->pos
.v
+= 28;
678 add234(mcs
->byctrl
, mc
);
679 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
680 mcs
->panels
[curstate
->panelnum
] = mc
;
681 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
684 #if !TARGET_API_MAC_CARBON
685 static pascal SInt32
macctrl_sys7_editbox_cdef(SInt16 variant
,
687 ControlDefProcMessage msg
,
698 rect
= (*control
)->contrlRect
;
699 if (variant
== SYS7_EDITBOX_VARIANT
)
700 InsetRect(&rect
, 3, 3); /* 2 if it's 20 pixels high */
701 te
= TENew(&rect
, &rect
);
702 ssfs
= GetScriptVariable(smSystemScript
, smScriptSysFondSize
);
703 (*te
)->txSize
= LoWord(ssfs
);
704 (*te
)->txFont
= HiWord(ssfs
);
705 (*control
)->contrlData
= (Handle
)te
;
708 TEDispose((TEHandle
)(*control
)->contrlData
);
711 if ((*control
)->contrlVis
) {
712 rect
= (*control
)->contrlRect
;
713 if (variant
== SYS7_EDITBOX_VARIANT
) {
716 InsetRect(&rect
, 3, 3);
719 (*(TEHandle
)(*control
)->contrlData
)->viewRect
= rect
;
720 TEUpdate(&rect
, (TEHandle
)(*control
)->contrlData
);
724 if (variant
== SYS7_TEXT_VARIANT
)
725 return kControlNoPart
;
726 mouse
.h
= LoWord(param
);
727 mouse
.v
= HiWord(param
);
728 rect
= (*control
)->contrlRect
;
729 InsetRect(&rect
, 3, 3);
730 return PtInRect(mouse
, &rect
) ? kControlEditTextPart
: kControlNoPart
;
732 if (param
& (1 << 31)) {
738 rgn
= (RgnHandle
)param
;
739 RectRgn(rgn
, &(*control
)->contrlRect
);
743 rgn
= (RgnHandle
)param
;
752 static void macctrl_radio(struct macctrls
*mcs
, WindowPtr window
,
753 struct mac_layoutstate
*curstate
,
756 union macctrl
*mc
= snew(union macctrl
);
759 unsigned int i
, colwidth
;
761 mc
->generic
.type
= MACCTRL_RADIO
;
762 mc
->generic
.ctrl
= ctrl
;
763 mc
->generic
.privdata
= NULL
;
764 mc
->radio
.tbctrls
= snewn(ctrl
->radio
.nbuttons
, ControlRef
);
765 colwidth
= (curstate
->width
+ 13) / ctrl
->radio
.ncolumns
;
766 bounds
.top
= curstate
->pos
.v
;
767 bounds
.bottom
= bounds
.top
+ 16;
768 bounds
.left
= curstate
->pos
.h
;
769 bounds
.right
= bounds
.left
+ curstate
->width
;
770 if (ctrl
->radio
.label
== NULL
)
771 mc
->radio
.tblabel
= NULL
;
773 if (mac_gestalts
.apprvers
>= 0x100) {
774 mc
->radio
.tblabel
= NewControl(window
, &bounds
, NULL
, FALSE
,
775 0, 0, 0, kControlStaticTextProc
,
777 SetControlData(mc
->radio
.tblabel
, kControlEntireControl
,
778 kControlStaticTextTextTag
,
779 strlen(ctrl
->radio
.label
), ctrl
->radio
.label
);
781 #if !TARGET_API_MAC_CARBON
783 mc
->radio
.tblabel
= NewControl(window
, &bounds
, NULL
, FALSE
,
784 0, 0, 0, SYS7_TEXT_PROC
, (long)mc
);
785 TESetText(ctrl
->radio
.label
, strlen(ctrl
->radio
.label
),
786 (TEHandle
)(*mc
->radio
.tblabel
)->contrlData
);
789 curstate
->pos
.v
+= 18;
791 for (i
= 0; i
< ctrl
->radio
.nbuttons
; i
++) {
792 bounds
.top
= curstate
->pos
.v
- 2;
793 bounds
.bottom
= bounds
.top
+ 18;
794 bounds
.left
= curstate
->pos
.h
+ colwidth
* (i
% ctrl
->radio
.ncolumns
);
795 if (i
== ctrl
->radio
.nbuttons
- 1 ||
796 i
% ctrl
->radio
.ncolumns
== ctrl
->radio
.ncolumns
- 1) {
797 bounds
.right
= curstate
->pos
.h
+ curstate
->width
;
798 curstate
->pos
.v
+= 18;
800 bounds
.right
= bounds
.left
+ colwidth
- 13;
801 c2pstrcpy(title
, ctrl
->radio
.buttons
[i
]);
802 mc
->radio
.tbctrls
[i
] = NewControl(window
, &bounds
, title
, FALSE
,
803 0, 0, 1, radioButProc
, (long)mc
);
805 curstate
->pos
.v
+= 4;
806 add234(mcs
->byctrl
, mc
);
807 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
808 mcs
->panels
[curstate
->panelnum
] = mc
;
809 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
812 static void macctrl_checkbox(struct macctrls
*mcs
, WindowPtr window
,
813 struct mac_layoutstate
*curstate
,
816 union macctrl
*mc
= snew(union macctrl
);
820 assert(ctrl
->checkbox
.label
!= NULL
);
821 mc
->generic
.type
= MACCTRL_CHECKBOX
;
822 mc
->generic
.ctrl
= ctrl
;
823 mc
->generic
.privdata
= NULL
;
824 bounds
.left
= curstate
->pos
.h
;
825 bounds
.right
= bounds
.left
+ curstate
->width
;
826 bounds
.top
= curstate
->pos
.v
;
827 bounds
.bottom
= bounds
.top
+ 16;
828 c2pstrcpy(title
, ctrl
->checkbox
.label
);
829 mc
->checkbox
.tbctrl
= NewControl(window
, &bounds
, title
, FALSE
, 0, 0, 1,
830 checkBoxProc
, (long)mc
);
831 add234(mcs
->byctrl
, mc
);
832 curstate
->pos
.v
+= 22;
833 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
834 mcs
->panels
[curstate
->panelnum
] = mc
;
835 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
838 static void macctrl_button(struct macctrls
*mcs
, WindowPtr window
,
839 struct mac_layoutstate
*curstate
,
842 union macctrl
*mc
= snew(union macctrl
);
846 assert(ctrl
->button
.label
!= NULL
);
847 mc
->generic
.type
= MACCTRL_BUTTON
;
848 mc
->generic
.ctrl
= ctrl
;
849 mc
->generic
.privdata
= NULL
;
850 bounds
.left
= curstate
->pos
.h
;
851 bounds
.right
= bounds
.left
+ curstate
->width
;
852 bounds
.top
= curstate
->pos
.v
;
853 bounds
.bottom
= bounds
.top
+ 20;
854 c2pstrcpy(title
, ctrl
->button
.label
);
855 mc
->button
.tbctrl
= NewControl(window
, &bounds
, title
, FALSE
, 0, 0, 1,
856 pushButProc
, (long)mc
);
857 mc
->button
.tbring
= NULL
;
858 if (mac_gestalts
.apprvers
>= 0x100) {
859 Boolean isdefault
= ctrl
->button
.isdefault
;
861 SetControlData(mc
->button
.tbctrl
, kControlEntireControl
,
862 kControlPushButtonDefaultTag
,
863 sizeof(isdefault
), &isdefault
);
864 } else if (ctrl
->button
.isdefault
) {
865 InsetRect(&bounds
, -4, -4);
866 mc
->button
.tbring
= NewControl(window
, &bounds
, title
, FALSE
, 0, 0, 1,
867 SYS7_DEFAULT_PROC
, (long)mc
);
869 if (mac_gestalts
.apprvers
>= 0x110) {
870 Boolean iscancel
= ctrl
->button
.iscancel
;
872 SetControlData(mc
->button
.tbctrl
, kControlEntireControl
,
873 kControlPushButtonCancelTag
,
874 sizeof(iscancel
), &iscancel
);
876 if (ctrl
->button
.isdefault
)
878 if (ctrl
->button
.iscancel
)
880 add234(mcs
->byctrl
, mc
);
881 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
882 mcs
->panels
[curstate
->panelnum
] = mc
;
883 curstate
->pos
.v
+= 26;
886 #if !TARGET_API_MAC_CARBON
887 static pascal SInt32
macctrl_sys7_default_cdef(SInt16 variant
,
889 ControlDefProcMessage msg
,
899 if ((*control
)->contrlVis
) {
900 rect
= (*control
)->contrlRect
;
901 GetPenState(&savestate
);
904 if ((*control
)->contrlHilite
== kControlInactivePart
)
906 oval
= (rect
.bottom
- rect
.top
) / 2 + 2;
907 FrameRoundRect(&rect
, oval
, oval
);
908 SetPenState(&savestate
);
912 if (param
& (1 << 31)) {
918 rgn
= (RgnHandle
)param
;
919 RectRgn(rgn
, &(*control
)->contrlRect
);
923 rgn
= (RgnHandle
)param
;
932 static void macctrl_listbox(struct macctrls
*mcs
, WindowPtr window
,
933 struct mac_layoutstate
*curstate
,
936 union macctrl
*mc
= snew(union macctrl
);
937 Rect bounds
, upbounds
, downbounds
;
941 assert(ctrl
->listbox
.percentwidth
== 100);
942 mc
->generic
.type
= MACCTRL_LISTBOX
;
943 mc
->generic
.ctrl
= ctrl
;
944 mc
->generic
.privdata
= NULL
;
945 /* The list starts off empty */
946 mc
->listbox
.nids
= 0;
947 mc
->listbox
.ids
= NULL
;
948 bounds
.left
= curstate
->pos
.h
;
949 bounds
.right
= bounds
.left
+ curstate
->width
;
950 bounds
.top
= curstate
->pos
.v
;
951 bounds
.bottom
= bounds
.top
+ 16 * ctrl
->listbox
.height
+ 2;
953 if (ctrl
->listbox
.draglist
) {
954 upbounds
= downbounds
= bounds
;
955 upbounds
.left
= upbounds
.right
- 58;
956 upbounds
.bottom
= upbounds
.top
+ 20;
957 downbounds
.left
= downbounds
.right
- 58;
958 downbounds
.top
= upbounds
.bottom
+ 6;
959 downbounds
.bottom
= downbounds
.top
+ 20;
960 bounds
.right
-= 64; /* enough for 6 px gap and a button */
963 if (mac_gestalts
.apprvers
>= 0x100) {
964 InsetRect(&bounds
, 3, 3);
965 mc
->listbox
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
,
967 kControlListBoxProc
, (long)mc
);
968 if (GetControlData(mc
->listbox
.tbctrl
, kControlEntireControl
,
969 kControlListBoxListHandleTag
,
970 sizeof(mc
->listbox
.list
), &mc
->listbox
.list
,
972 DisposeControl(mc
->listbox
.tbctrl
);
977 #if !TARGET_API_MAC_CARBON
979 InsetRect(&bounds
, -3, -3);
980 mc
->listbox
.tbctrl
= NewControl(window
, &bounds
, NULL
, FALSE
,
982 SYS7_LISTBOX_PROC
, (long)mc
);
983 mc
->listbox
.list
= (ListHandle
)(*mc
->listbox
.tbctrl
)->contrlData
;
984 (*mc
->listbox
.list
)->refCon
= (long)mc
;
987 if (!ctrl
->listbox
.multisel
) {
988 #if TARGET_API_MAC_CARBON
989 SetListSelectionFlags(mc
->listbox
.list
, lOnlyOne
);
991 (*mc
->listbox
.list
)->selFlags
= lOnlyOne
;
995 if (ctrl
->listbox
.draglist
) {
996 mc
->listbox
.tbup
= NewControl(window
, &upbounds
, "\pUp", FALSE
, 0, 0, 1,
997 pushButProc
, (long)mc
);
998 mc
->listbox
.tbdown
= NewControl(window
, &downbounds
, "\pDown", FALSE
, 0, 0, 1,
999 pushButProc
, (long)mc
);
1002 add234(mcs
->byctrl
, mc
);
1003 curstate
->pos
.v
+= 6 + 16 * ctrl
->listbox
.height
+ 2;
1004 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
1005 mcs
->panels
[curstate
->panelnum
] = mc
;
1006 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
1007 #if TARGET_API_MAC_CARBON
1008 HideControl(GetListVerticalScrollBar(mc
->listbox
.list
));
1010 HideControl((*mc
->listbox
.list
)->vScroll
);
1014 #if !TARGET_API_MAC_CARBON
1015 static pascal SInt32
macctrl_sys7_listbox_cdef(SInt16 variant
,
1017 ControlDefProcMessage msg
,
1033 rect
= (*control
)->contrlRect
;
1034 InsetRect(&rect
, 4, 4);
1035 rect
.right
-= 15; /* scroll bar */
1036 bounds
.top
= bounds
.bottom
= bounds
.left
= 0;
1038 csize
.h
= csize
.v
= 0;
1040 savefont
= curport
->txFont
;
1041 savesize
= curport
->txSize
;
1042 ssfs
= GetScriptVariable(smSystemScript
, smScriptSysFondSize
);
1043 TextFont(HiWord(ssfs
));
1044 TextSize(LoWord(ssfs
));
1045 list
= LNew(&rect
, &bounds
, csize
, 0, (*control
)->contrlOwner
,
1046 TRUE
, FALSE
, FALSE
, TRUE
);
1047 SetControlReference((*list
)->vScroll
, (long)list
);
1048 (*control
)->contrlData
= (Handle
)list
;
1054 * If the dialogue box is being destroyed, the scroll bar
1055 * might have gone already. In our situation, this is the
1056 * only time we destroy a control, so NULL out the scroll bar
1057 * handle to prevent LDispose trying to free it.
1059 list
= (ListHandle
)(*control
)->contrlData
;
1060 (*list
)->vScroll
= NULL
;
1064 if ((*control
)->contrlVis
) {
1065 rect
= (*control
)->contrlRect
;
1066 /* XXX input focus highlighting? */
1067 InsetRect(&rect
, 3, 3);
1070 list
= (ListHandle
)(*control
)->contrlData
;
1071 LActivate((*control
)->contrlHilite
!= kControlInactivePart
, list
);
1073 LUpdate(curport
->visRgn
, list
);
1077 mouse
.h
= LoWord(param
);
1078 mouse
.v
= HiWord(param
);
1079 rect
= (*control
)->contrlRect
;
1080 InsetRect(&rect
, 4, 4);
1082 * We deliberately exclude the scrollbar so that LClick() can see it.
1085 return PtInRect(mouse
, &rect
) ? kControlListBoxPart
: kControlNoPart
;
1087 if (param
& (1 << 31)) {
1088 param
&= ~(1 << 31);
1093 rgn
= (RgnHandle
)param
;
1094 RectRgn(rgn
, &(*control
)->contrlRect
);
1098 rgn
= (RgnHandle
)param
;
1107 #if !TARGET_API_MAC_CARBON
1108 static pascal SInt32
macctrl_sys7_groupbox_cdef(SInt16 variant
,
1110 ControlDefProcMessage msg
,
1119 if ((*control
)->contrlVis
) {
1120 rect
= (*control
)->contrlRect
;
1121 GetPenState(&savestate
);
1126 SetPenState(&savestate
);
1130 if (param
& (1 << 31)) {
1131 param
&= ~(1 << 31);
1136 rgn
= (RgnHandle
)param
;
1137 RectRgn(rgn
, &(*control
)->contrlRect
);
1141 rgn
= (RgnHandle
)param
;
1149 static void macctrl_popup(struct macctrls
*mcs
, WindowPtr window
,
1150 struct mac_layoutstate
*curstate
,
1151 union control
*ctrl
)
1153 union macctrl
*mc
= snew(union macctrl
);
1156 unsigned int labelwidth
;
1157 static int nextmenuid
= MENU_MIN
;
1162 * <http://developer.apple.com/qa/tb/tb42.html> explains how to
1163 * create a popup menu with dynamic content.
1165 assert(ctrl
->listbox
.height
== 0);
1166 assert(!ctrl
->listbox
.draglist
);
1167 assert(!ctrl
->listbox
.multisel
);
1169 mc
->generic
.type
= MACCTRL_POPUP
;
1170 mc
->generic
.ctrl
= ctrl
;
1171 mc
->generic
.privdata
= NULL
;
1172 c2pstrcpy(title
, ctrl
->button
.label
== NULL ?
"" : ctrl
->button
.label
);
1174 /* Find a spare menu ID and create the menu */
1175 while (GetMenuHandle(nextmenuid
) != NULL
)
1176 if (++nextmenuid
>= MENU_MAX
) nextmenuid
= MENU_MIN
;
1177 menuid
= nextmenuid
++;
1178 menu
= NewMenu(menuid
, "\pdummy");
1179 if (menu
== NULL
) return;
1180 mc
->popup
.menu
= menu
;
1181 mc
->popup
.menuid
= menuid
;
1182 InsertMenu(menu
, kInsertHierarchicalMenu
);
1184 /* The menu starts off empty */
1186 mc
->popup
.ids
= NULL
;
1188 bounds
.left
= curstate
->pos
.h
;
1189 bounds
.right
= bounds
.left
+ curstate
->width
;
1190 bounds
.top
= curstate
->pos
.v
;
1191 bounds
.bottom
= bounds
.top
+ 20;
1192 /* XXX handle percentwidth == 100 */
1193 labelwidth
= curstate
->width
* (100 - ctrl
->listbox
.percentwidth
) / 100;
1194 mc
->popup
.tbctrl
= NewControl(window
, &bounds
, title
, FALSE
,
1195 popupTitleLeftJust
, menuid
, labelwidth
,
1196 popupMenuProc
+ popupFixedWidth
, (long)mc
);
1197 add234(mcs
->byctrl
, mc
);
1198 curstate
->pos
.v
+= 26;
1199 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
1200 mcs
->panels
[curstate
->panelnum
] = mc
;
1201 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
1204 static void macctrl_groupbox(struct macctrls
*mcs
, WindowPtr window
,
1205 struct mac_layoutstate
*curstate
,
1206 union control
*ctrl
)
1208 union macctrl
*mc
= snew (union macctrl
);
1212 r
.top
= curstate
->boxpos
.v
;
1213 r
.left
= curstate
->boxpos
.h
;
1214 r
.bottom
= curstate
->pos
.v
;
1215 r
.right
= curstate
->boxpos
.h
+ curstate
->width
;
1217 mc
->generic
.type
= MACCTRL_GROUPBOX
;
1218 mc
->generic
.privdata
= NULL
;
1219 mc
->generic
.ctrl
= ctrl
;
1220 mc
->generic
.ctrl
->generic
.handler
= NULL
;
1222 if (curstate
->boxname
)
1223 c2pstrcpy(ptitle
, curstate
->boxname
);
1225 c2pstrcpy(ptitle
, "");
1226 if (mac_gestalts
.apprvers
>= 0x100) { /* Appearance Manager */
1227 mc
->groupbox
.tbctrl
= NewControl(window
, &r
, ptitle
, FALSE
, 0, 0, 1,
1228 kControlGroupBoxTextTitleProc
, (long)mc
);
1230 mc
->groupbox
.tbctrl
= NewControl(window
, &r
, ptitle
, FALSE
, 0, 0, 1,
1231 SYS7_GROUPBOX_PROC
, (long)mc
);
1233 add234(mcs
->byctrl
, mc
);
1234 mc
->generic
.next
= mcs
->panels
[curstate
->panelnum
];
1235 mcs
->panels
[curstate
->panelnum
] = mc
;
1238 void macctrl_activate(WindowPtr window
, EventRecord
*event
)
1240 struct macctrls
*mcs
= mac_winctrls(window
);
1241 Boolean active
= (event
->modifiers
& activeFlag
) != 0;
1244 ControlPartCode state
;
1248 SetPort((GrafPtr
)GetWindowPort(window
));
1249 if (mac_gestalts
.apprvers
>= 0x100)
1250 SetThemeWindowBackground(window
, active ?
1251 kThemeBrushModelessDialogBackgroundActive
:
1252 kThemeBrushModelessDialogBackgroundInactive
,
1254 state
= active ? kControlNoPart
: kControlInactivePart
;
1255 for (i
= 0; i
<= mcs
->curpanel
; i
+= mcs
->curpanel
)
1256 for (mc
= mcs
->panels
[i
]; mc
!= NULL
; mc
= mc
->generic
.next
) {
1257 switch (mc
->generic
.type
) {
1259 HiliteControl(mc
->text
.tbctrl
, state
);
1261 case MACCTRL_EDITBOX
:
1262 HiliteControl(mc
->editbox
.tbctrl
, state
);
1263 if (mc
->editbox
.tblabel
!= NULL
)
1264 HiliteControl(mc
->editbox
.tblabel
, state
);
1265 if (mc
->editbox
.tbbutton
!= NULL
)
1266 HiliteControl(mc
->editbox
.tbbutton
, state
);
1269 for (j
= 0; j
< mc
->generic
.ctrl
->radio
.nbuttons
; j
++)
1270 HiliteControl(mc
->radio
.tbctrls
[j
], state
);
1271 if (mc
->radio
.tblabel
!= NULL
)
1272 HiliteControl(mc
->radio
.tblabel
, state
);
1274 case MACCTRL_CHECKBOX
:
1275 HiliteControl(mc
->checkbox
.tbctrl
, state
);
1277 case MACCTRL_BUTTON
:
1278 HiliteControl(mc
->button
.tbctrl
, state
);
1279 if (mc
->button
.tbring
!= NULL
)
1280 HiliteControl(mc
->button
.tbring
, state
);
1282 case MACCTRL_LISTBOX
:
1283 HiliteControl(mc
->listbox
.tbctrl
, state
);
1284 if (mc
->listbox
.tbup
!= NULL
)
1285 HiliteControl(mc
->listbox
.tbup
, state
);
1286 if (mc
->listbox
.tbdown
!= NULL
)
1287 HiliteControl(mc
->listbox
.tbdown
, state
);
1290 HiliteControl(mc
->popup
.tbctrl
, state
);
1292 case MACCTRL_GROUPBOX
:
1293 HiliteControl(mc
->popup
.tbctrl
, state
);
1295 #if !TARGET_API_MAC_CARBON
1296 if (mcs
->focus
== mc
) {
1298 macctrl_enfocus(mc
);
1300 macctrl_defocus(mc
);
1307 void macctrl_click(WindowPtr window
, EventRecord
*event
)
1310 ControlHandle control
, oldfocus
;
1311 int part
, trackresult
;
1314 struct macctrls
*mcs
= mac_winctrls(window
);
1319 SetPort((GrafPtr
)GetWindowPort(window
));
1320 mouse
= event
->where
;
1321 GlobalToLocal(&mouse
);
1322 part
= FindControl(mouse
, window
, &control
);
1323 if (control
!= NULL
) {
1324 #if !TARGET_API_MAC_CARBON
1326 * Special magic for scroll bars in list boxes, whose refcon
1329 if (part
== kControlUpButtonPart
|| part
== kControlDownButtonPart
||
1330 part
== kControlPageUpPart
|| part
== kControlPageDownPart
||
1331 part
== kControlIndicatorPart
)
1332 mc
= (union macctrl
*)
1333 (*(ListHandle
)GetControlReference(control
))->refCon
;
1336 mc
= (union macctrl
*)GetControlReference(control
);
1337 if (mac_gestalts
.apprvers
>= 0x100) {
1338 if (GetControlFeatures(control
, &features
) == noErr
&&
1339 (features
& kControlSupportsFocus
) &&
1340 (features
& kControlGetsFocusOnClick
) &&
1341 GetKeyboardFocus(window
, &oldfocus
) == noErr
&&
1342 control
!= oldfocus
)
1343 SetKeyboardFocus(window
, control
, part
);
1344 trackresult
= HandleControlClick(control
, mouse
, event
->modifiers
,
1345 (ControlActionUPP
)-1);
1347 #if !TARGET_API_MAC_CARBON
1348 if (mc
->generic
.type
== MACCTRL_EDITBOX
&&
1349 control
== mc
->editbox
.tbctrl
) {
1350 TEHandle te
= (TEHandle
)(*control
)->contrlData
;
1352 macctrl_setfocus(mcs
, mc
);
1353 TEClick(mouse
, !!(event
->modifiers
& shiftKey
), te
);
1356 if (mc
->generic
.type
== MACCTRL_EDITBOX
&&
1357 control
== mc
->editbox
.tbbutton
) {
1358 dlg_editbox_set(mc
->generic
.ctrl
, mcs
,
1359 cp_enumerate(dlg_listbox_index(mc
->generic
.ctrl
, mcs
)));
1360 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1362 if (mc
->generic
.type
== MACCTRL_LISTBOX
&&
1363 (control
== mc
->listbox
.tbctrl
||
1364 control
== (*mc
->listbox
.list
)->vScroll
)) {
1366 macctrl_setfocus(mcs
, mc
);
1367 if (LClick(mouse
, event
->modifiers
, mc
->listbox
.list
))
1369 ctrlevent(mcs
, mc
, EVENT_ACTION
);
1371 ctrlevent(mcs
, mc
, EVENT_SELCHANGE
);
1374 if (mc
->generic
.type
== MACCTRL_LISTBOX
&&
1375 control
== mc
->listbox
.tbup
)
1376 draglist_up(mc
, mcs
);
1377 if (mc
->generic
.type
== MACCTRL_LISTBOX
&&
1378 control
== mc
->listbox
.tbdown
)
1379 draglist_down(mc
, mcs
);
1381 trackresult
= TrackControl(control
, mouse
, (ControlActionUPP
)-1);
1383 switch (mc
->generic
.type
) {
1385 if (trackresult
!= 0) {
1386 for (i
= 0; i
< mc
->generic
.ctrl
->radio
.nbuttons
; i
++)
1387 if (mc
->radio
.tbctrls
[i
] == control
)
1388 SetControlValue(mc
->radio
.tbctrls
[i
],
1389 kControlRadioButtonCheckedValue
);
1391 SetControlValue(mc
->radio
.tbctrls
[i
],
1392 kControlRadioButtonUncheckedValue
);
1393 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1396 case MACCTRL_CHECKBOX
:
1397 if (trackresult
!= 0) {
1398 SetControlValue(control
, !GetControlValue(control
));
1399 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1402 case MACCTRL_BUTTON
:
1403 if (trackresult
!= 0)
1404 ctrlevent(mcs
, mc
, EVENT_ACTION
);
1406 case MACCTRL_EDITBOX
:
1407 if (control
== mc
->editbox
.tbbutton
) {
1408 dlg_editbox_set(mc
->generic
.ctrl
, mcs
,
1409 cp_enumerate(dlg_listbox_index(mc
->generic
.ctrl
, mcs
)));
1410 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1413 case MACCTRL_LISTBOX
:
1414 if (control
== mc
->listbox
.tbup
)
1415 draglist_up(mc
, mcs
);
1416 if (control
== mc
->listbox
.tbdown
)
1417 draglist_down(mc
, mcs
);
1419 /* FIXME spot double-click */
1420 ctrlevent(mcs
, mc
, EVENT_SELCHANGE
);
1423 ctrlevent(mcs
, mc
, EVENT_SELCHANGE
);
1431 void macctrl_key(WindowPtr window
, EventRecord
*event
)
1434 struct macctrls
*mcs
= mac_winctrls(window
);
1436 unsigned long dummy
;
1438 switch (event
->message
& charCodeMask
) {
1439 case kEnterCharCode
:
1440 case kReturnCharCode
:
1441 if (mcs
->defbutton
!= NULL
) {
1442 assert(mcs
->defbutton
->generic
.type
== MACCTRL_BUTTON
);
1443 HiliteControl(mcs
->defbutton
->button
.tbctrl
, kControlButtonPart
);
1445 * I'd like to delay unhilighting the button until after
1446 * the event has been processed, but by them the entire
1447 * dialgue box might have been destroyed.
1450 HiliteControl(mcs
->defbutton
->button
.tbctrl
, kControlNoPart
);
1451 ctrlevent(mcs
, mcs
->defbutton
, EVENT_ACTION
);
1454 case kEscapeCharCode
:
1455 if (mcs
->canbutton
!= NULL
) {
1456 assert(mcs
->canbutton
->generic
.type
== MACCTRL_BUTTON
);
1457 HiliteControl(mcs
->canbutton
->button
.tbctrl
, kControlButtonPart
);
1459 HiliteControl(mcs
->defbutton
->button
.tbctrl
, kControlNoPart
);
1460 ctrlevent(mcs
, mcs
->canbutton
, EVENT_ACTION
);
1464 if (mac_gestalts
.apprvers
>= 0x100) {
1465 if (GetKeyboardFocus(window
, &control
) == noErr
&& control
!= NULL
) {
1466 HandleControlKey(control
, (event
->message
& keyCodeMask
) >> 8,
1467 event
->message
& charCodeMask
, event
->modifiers
);
1468 mc
= (union macctrl
*)GetControlReference(control
);
1469 switch (mc
->generic
.type
) {
1470 case MACCTRL_LISTBOX
:
1471 ctrlevent(mcs
, mc
, EVENT_SELCHANGE
);
1474 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1479 #if !TARGET_API_MAC_CARBON
1483 if (mcs
->focus
!= NULL
) {
1485 switch (mc
->generic
.type
) {
1486 case MACCTRL_EDITBOX
:
1487 te
= (TEHandle
)(*mc
->editbox
.tbctrl
)->contrlData
;
1488 TEKey(event
->message
& charCodeMask
, te
);
1489 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
1497 void macctrl_update(WindowPtr window
)
1499 #if TARGET_API_MAC_CARBON
1505 BeginUpdate(window
);
1507 SetPort((GrafPtr
)GetWindowPort(window
));
1508 if (mac_gestalts
.apprvers
>= 0x101) {
1509 #if TARGET_API_MAC_CARBON
1510 GetPortBounds(GetWindowPort(window
), &rect
);
1512 rect
= window
->portRect
;
1514 InsetRect(&rect
, -1, -1);
1515 DrawThemeModelessDialogFrame(&rect
, mac_frontwindow() == window ?
1516 kThemeStateActive
: kThemeStateInactive
);
1518 #if TARGET_API_MAC_CARBON
1520 GetPortVisibleRegion(GetWindowPort(window
), visrgn
);
1521 UpdateControls(window
, visrgn
);
1524 UpdateControls(window
, window
->visRgn
);
1530 #if TARGET_API_MAC_CARBON
1531 #define EnableItem EnableMenuItem
1532 #define DisableItem DisableMenuItem
1534 void macctrl_adjustmenus(WindowPtr window
)
1538 menu
= GetMenuHandle(mFile
);
1539 DisableItem(menu
, iSave
); /* XXX enable if modified */
1540 EnableItem(menu
, iSaveAs
);
1541 EnableItem(menu
, iDuplicate
);
1543 menu
= GetMenuHandle(mEdit
);
1544 DisableItem(menu
, 0);
1547 void macctrl_close(WindowPtr window
)
1549 struct macctrls
*mcs
= mac_winctrls(window
);
1553 * Mostly, we don't bother disposing of the Toolbox controls,
1554 * since that will happen automatically when the window is
1555 * disposed of. Popup menus are an exception, because we have to
1556 * dispose of the menu ourselves, and doing that while the control
1557 * still holds a reference to it seems rude.
1559 while ((mc
= index234(mcs
->byctrl
, 0)) != NULL
) {
1560 if (mc
->generic
.privdata
!= NULL
&& mc
->generic
.freeprivdata
)
1561 sfree(mc
->generic
.privdata
);
1562 switch (mc
->generic
.type
) {
1564 DisposeControl(mc
->popup
.tbctrl
);
1565 DeleteMenu(mc
->popup
.menuid
);
1566 DisposeMenu(mc
->popup
.menu
);
1569 del234(mcs
->byctrl
, mc
);
1573 freetree234(mcs
->byctrl
);
1579 void dlg_update_start(union control
*ctrl
, void *dlg
)
1585 void dlg_update_done(union control
*ctrl
, void *dlg
)
1591 void dlg_set_focus(union control
*ctrl
, void *dlg
)
1594 if (mac_gestalts
.apprvers
>= 0x100) {
1595 /* Use SetKeyboardFocus() */
1597 /* Do our own mucking around */
1601 union control
*dlg_last_focused(union control
*ctrl
, void *dlg
)
1607 void dlg_beep(void *dlg
)
1613 void dlg_error_msg(void *dlg
, char *msg
)
1617 c2pstrcpy(pmsg
, msg
);
1618 ParamText(pmsg
, NULL
, NULL
, NULL
);
1619 StopAlert(128, NULL
);
1622 void dlg_end(void *dlg
, int value
)
1624 struct macctrls
*mcs
= dlg
;
1626 if (mcs
->end
!= NULL
)
1627 (*mcs
->end
)(mcs
->window
, value
);
1630 void dlg_refresh(union control
*ctrl
, void *dlg
)
1632 struct macctrls
*mcs
= dlg
;
1637 /* NULL means refresh every control */
1638 for (i
= 0 ; i
< mcs
->npanels
; i
++) {
1639 for (mc
= mcs
->panels
[i
]; mc
!= NULL
; mc
= mc
->generic
.next
) {
1640 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
1645 /* Just refresh a specific control */
1646 mc
= findbyctrl(mcs
, ctrl
);
1648 ctrlevent(mcs
, mc
, EVENT_REFRESH
);
1651 void *dlg_get_privdata(union control
*ctrl
, void *dlg
)
1653 struct macctrls
*mcs
= dlg
;
1654 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1657 return mc
->generic
.privdata
;
1660 void dlg_set_privdata(union control
*ctrl
, void *dlg
, void *ptr
)
1662 struct macctrls
*mcs
= dlg
;
1663 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1666 mc
->generic
.privdata
= ptr
;
1667 mc
->generic
.freeprivdata
= FALSE
;
1670 void *dlg_alloc_privdata(union control
*ctrl
, void *dlg
, size_t size
)
1672 struct macctrls
*mcs
= dlg
;
1673 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1676 mc
->generic
.privdata
= smalloc(size
);
1677 mc
->generic
.freeprivdata
= TRUE
;
1678 return mc
->generic
.privdata
;
1683 * Radio Button control
1686 void dlg_radiobutton_set(union control
*ctrl
, void *dlg
, int whichbutton
)
1688 struct macctrls
*mcs
= dlg
;
1689 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1692 if (mc
== NULL
) return;
1693 for (i
= 0; i
< ctrl
->radio
.nbuttons
; i
++) {
1694 if (i
== whichbutton
)
1695 SetControlValue(mc
->radio
.tbctrls
[i
],
1696 kControlRadioButtonCheckedValue
);
1698 SetControlValue(mc
->radio
.tbctrls
[i
],
1699 kControlRadioButtonUncheckedValue
);
1704 int dlg_radiobutton_get(union control
*ctrl
, void *dlg
)
1706 struct macctrls
*mcs
= dlg
;
1707 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1711 for (i
= 0; i
< ctrl
->radio
.nbuttons
; i
++) {
1712 if (GetControlValue(mc
->radio
.tbctrls
[i
]) ==
1713 kControlRadioButtonCheckedValue
)
1724 void dlg_checkbox_set(union control
*ctrl
, void *dlg
, int checked
)
1726 struct macctrls
*mcs
= dlg
;
1727 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1729 if (mc
== NULL
) return;
1730 SetControlValue(mc
->checkbox
.tbctrl
,
1731 checked ? kControlCheckBoxCheckedValue
:
1732 kControlCheckBoxUncheckedValue
);
1735 int dlg_checkbox_get(union control
*ctrl
, void *dlg
)
1737 struct macctrls
*mcs
= dlg
;
1738 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1741 return GetControlValue(mc
->checkbox
.tbctrl
);
1749 void dlg_editbox_set(union control
*ctrl
, void *dlg
, char const *text
)
1751 struct macctrls
*mcs
= dlg
;
1752 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1755 if (mc
== NULL
) return;
1756 assert(mc
->generic
.type
== MACCTRL_EDITBOX
);
1758 SetPort((GrafPtr
)(GetWindowPort(mcs
->window
)));
1759 if (mac_gestalts
.apprvers
>= 0x100)
1760 SetControlData(mc
->editbox
.tbctrl
, kControlEntireControl
,
1761 ctrl
->editbox
.password ?
1762 kControlEditTextPasswordTag
:
1763 kControlEditTextTextTag
,
1764 strlen(text
), text
);
1765 #if !TARGET_API_MAC_CARBON
1767 TESetText(text
, strlen(text
),
1768 (TEHandle
)(*mc
->editbox
.tbctrl
)->contrlData
);
1770 DrawOneControl(mc
->editbox
.tbctrl
);
1774 void dlg_editbox_get(union control
*ctrl
, void *dlg
, char *buffer
, int length
)
1776 struct macctrls
*mcs
= dlg
;
1777 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1781 assert(mc
->generic
.type
== MACCTRL_EDITBOX
);
1782 if (mac_gestalts
.apprvers
>= 0x100) {
1783 if (GetControlData(mc
->editbox
.tbctrl
, kControlEntireControl
,
1784 ctrl
->editbox
.password ?
1785 kControlEditTextPasswordTag
:
1786 kControlEditTextTextTag
,
1787 length
- 1, buffer
, &olen
) != noErr
)
1789 if (olen
> length
- 1)
1792 #if !TARGET_API_MAC_CARBON
1794 TEHandle te
= (TEHandle
)(*mc
->editbox
.tbctrl
)->contrlData
;
1796 olen
= (*te
)->teLength
;
1797 if (olen
> length
- 1)
1799 memcpy(buffer
, *(*te
)->hText
, olen
);
1802 buffer
[olen
] = '\0';
1810 static void dlg_macpopup_clear(union control
*ctrl
, void *dlg
)
1812 struct macctrls
*mcs
= dlg
;
1813 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1814 MenuRef menu
= mc
->popup
.menu
;
1817 if (mc
== NULL
) return;
1818 n
= CountMenuItems(menu
);
1819 for (i
= 0; i
< n
; i
++)
1820 DeleteMenuItem(menu
, n
- i
);
1822 sfree(mc
->popup
.ids
);
1823 mc
->popup
.ids
= NULL
;
1824 SetControlMaximum(mc
->popup
.tbctrl
, CountMenuItems(menu
));
1827 static void dlg_macedit_clear(union control
*ctrl
, void *dlg
)
1829 struct macctrls
*mcs
= dlg
;
1830 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1831 MenuRef menu
= mc
->editbox
.menu
;
1834 if (mc
== NULL
) return;
1835 n
= CountMenuItems(menu
);
1836 for (i
= 0; i
< n
; i
++)
1837 DeleteMenuItem(menu
, n
- i
);
1838 mc
->editbox
.nids
= 0;
1839 sfree(mc
->editbox
.ids
);
1840 mc
->editbox
.ids
= NULL
;
1841 SetControlMaximum(mc
->editbox
.tbbutton
, CountMenuItems(menu
));
1844 static void dlg_maclist_clear(union control
*ctrl
, void *dlg
)
1846 struct macctrls
*mcs
= dlg
;
1847 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1849 if (mc
== NULL
) return;
1850 LDelRow(0, 0, mc
->listbox
.list
);
1851 mc
->listbox
.nids
= 0;
1852 sfree(mc
->listbox
.ids
);
1853 mc
->listbox
.ids
= NULL
;
1854 DrawOneControl(mc
->listbox
.tbctrl
);
1857 void dlg_listbox_clear(union control
*ctrl
, void *dlg
)
1860 switch (ctrl
->generic
.type
) {
1862 if (ctrl
->listbox
.height
== 0)
1863 dlg_macpopup_clear(ctrl
, dlg
);
1865 dlg_maclist_clear(ctrl
, dlg
);
1868 dlg_macedit_clear(ctrl
, dlg
);
1872 static void dlg_macpopup_del(union control
*ctrl
, void *dlg
, int index
)
1874 struct macctrls
*mcs
= dlg
;
1875 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1876 MenuRef menu
= mc
->popup
.menu
;
1878 if (mc
== NULL
) return;
1879 DeleteMenuItem(menu
, index
+ 1);
1880 if (mc
->popup
.ids
!= NULL
)
1881 memcpy(mc
->popup
.ids
+ index
, mc
->popup
.ids
+ index
+ 1,
1882 (mc
->popup
.nids
- index
- 1) * sizeof(*mc
->popup
.ids
));
1883 SetControlMaximum(mc
->popup
.tbctrl
, CountMenuItems(menu
));
1886 static void dlg_macedit_del(union control
*ctrl
, void *dlg
, int index
)
1888 struct macctrls
*mcs
= dlg
;
1889 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1890 MenuRef menu
= mc
->editbox
.menu
;
1892 if (mc
== NULL
) return;
1893 DeleteMenuItem(menu
, index
+ 1);
1894 if (mc
->editbox
.ids
!= NULL
)
1895 memcpy(mc
->editbox
.ids
+ index
, mc
->editbox
.ids
+ index
+ 1,
1896 (mc
->editbox
.nids
- index
- 1) * sizeof(*mc
->editbox
.ids
));
1897 SetControlMaximum(mc
->editbox
.tbbutton
, CountMenuItems(menu
));
1900 static void dlg_maclist_del(union control
*ctrl
, void *dlg
, int index
)
1902 struct macctrls
*mcs
= dlg
;
1903 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1905 if (mc
== NULL
) return;
1906 LDelRow(1, index
, mc
->listbox
.list
);
1907 if (mc
->listbox
.ids
!= NULL
)
1908 memcpy(mc
->listbox
.ids
+ index
, mc
->listbox
.ids
+ index
+ 1,
1909 (mc
->listbox
.nids
- index
- 1) * sizeof(*mc
->listbox
.ids
));
1910 DrawOneControl(mc
->listbox
.tbctrl
);
1913 void dlg_listbox_del(union control
*ctrl
, void *dlg
, int index
)
1916 switch (ctrl
->generic
.type
) {
1918 if (ctrl
->listbox
.height
== 0)
1919 dlg_macpopup_del(ctrl
, dlg
, index
);
1921 dlg_maclist_del(ctrl
, dlg
, index
);
1924 dlg_macedit_del(ctrl
, dlg
, index
);
1928 static void dlg_macpopup_add(union control
*ctrl
, void *dlg
, char const *text
)
1930 struct macctrls
*mcs
= dlg
;
1931 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1932 MenuRef menu
= mc
->popup
.menu
;
1935 if (mc
== NULL
) return;
1936 assert(text
[0] != '\0');
1937 c2pstrcpy(itemstring
, text
);
1938 AppendMenu(menu
, "\pdummy");
1939 SetMenuItemText(menu
, CountMenuItems(menu
), itemstring
);
1940 SetControlMaximum(mc
->popup
.tbctrl
, CountMenuItems(menu
));
1943 static void dlg_macedit_add(union control
*ctrl
, void *dlg
, char const *text
)
1945 struct macctrls
*mcs
= dlg
;
1946 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1947 MenuRef menu
= mc
->editbox
.menu
;
1950 if (mc
== NULL
) return;
1951 assert(text
[0] != '\0');
1952 c2pstrcpy(itemstring
, text
);
1953 AppendMenu(menu
, "\pdummy");
1954 SetMenuItemText(menu
, CountMenuItems(menu
), itemstring
);
1955 SetControlMaximum(mc
->editbox
.tbbutton
, CountMenuItems(menu
));
1958 static void dlg_maclist_add(union control
*ctrl
, void *dlg
, char const *text
)
1960 struct macctrls
*mcs
= dlg
;
1961 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1963 Cell cell
= { 0, 0 };
1965 if (mc
== NULL
) return;
1966 #if TARGET_API_MAC_CARBON
1967 GetListDataBounds(mc
->listbox
.list
, &bounds
);
1969 bounds
= (*mc
->listbox
.list
)->dataBounds
;
1971 cell
.v
= bounds
.bottom
;
1972 LAddRow(1, cell
.v
, mc
->listbox
.list
);
1973 LSetCell(text
, strlen(text
), cell
, mc
->listbox
.list
);
1974 DrawOneControl(mc
->listbox
.tbctrl
);
1977 void dlg_listbox_add(union control
*ctrl
, void *dlg
, char const *text
)
1980 switch (ctrl
->generic
.type
) {
1982 if (ctrl
->listbox
.height
== 0)
1983 dlg_macpopup_add(ctrl
, dlg
, text
);
1985 dlg_maclist_add(ctrl
, dlg
, text
);
1988 dlg_macedit_add(ctrl
, dlg
, text
);
1993 static void dlg_macpopup_addwithid(union control
*ctrl
, void *dlg
,
1994 char const *text
, int id
)
1996 struct macctrls
*mcs
= dlg
;
1997 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
1998 MenuRef menu
= mc
->popup
.menu
;
2001 if (mc
== NULL
) return;
2002 dlg_macpopup_add(ctrl
, dlg
, text
);
2003 index
= CountMenuItems(menu
) - 1;
2004 if (mc
->popup
.nids
<= index
) {
2005 mc
->popup
.nids
= index
+ 1;
2006 mc
->popup
.ids
= sresize(mc
->popup
.ids
, mc
->popup
.nids
, int);
2008 mc
->popup
.ids
[index
] = id
;
2011 static void dlg_macedit_addwithid(union control
*ctrl
, void *dlg
,
2012 char const *text
, int id
)
2014 struct macctrls
*mcs
= dlg
;
2015 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2016 MenuRef menu
= mc
->editbox
.menu
;
2019 if (mc
== NULL
) return;
2020 dlg_macedit_add(ctrl
, dlg
, text
);
2021 index
= CountMenuItems(menu
) - 1;
2022 if (mc
->editbox
.nids
<= index
) {
2023 mc
->editbox
.nids
= index
+ 1;
2024 mc
->editbox
.ids
= sresize(mc
->editbox
.ids
, mc
->editbox
.nids
, int);
2026 mc
->editbox
.ids
[index
] = id
;
2029 static void dlg_maclist_addwithid(union control
*ctrl
, void *dlg
,
2030 char const *text
, int id
)
2032 struct macctrls
*mcs
= dlg
;
2033 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2037 if (mc
== NULL
) return;
2038 dlg_maclist_add(ctrl
, dlg
, text
);
2039 #if TARGET_API_MAC_CARBON
2040 GetListDataBounds(mc
->listbox
.list
, &bounds
);
2042 bounds
= (*mc
->listbox
.list
)->dataBounds
;
2044 index
= bounds
.bottom
;
2045 if (mc
->listbox
.nids
<= index
) {
2046 mc
->listbox
.nids
= index
+ 1;
2047 mc
->listbox
.ids
= sresize(mc
->listbox
.ids
, mc
->listbox
.nids
, int);
2049 mc
->listbox
.ids
[index
] = id
;
2052 void dlg_listbox_addwithid(union control
*ctrl
, void *dlg
,
2053 char const *text
, int id
)
2056 switch (ctrl
->generic
.type
) {
2058 if (ctrl
->listbox
.height
== 0)
2059 dlg_macpopup_addwithid(ctrl
, dlg
, text
, id
);
2061 dlg_maclist_addwithid(ctrl
, dlg
, text
, id
);
2064 dlg_macedit_addwithid(ctrl
, dlg
, text
, id
);
2069 int dlg_listbox_getid(union control
*ctrl
, void *dlg
, int index
)
2071 struct macctrls
*mcs
= dlg
;
2072 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2075 switch (ctrl
->generic
.type
) {
2077 if (ctrl
->listbox
.height
== 0) {
2078 assert(mc
->popup
.ids
!= NULL
&& mc
->popup
.nids
> index
);
2079 return mc
->popup
.ids
[index
];
2081 assert(mc
->listbox
.ids
!= NULL
&& mc
->listbox
.nids
> index
);
2082 return mc
->listbox
.ids
[index
];
2085 assert(mc
->editbox
.ids
!= NULL
&& mc
->editbox
.nids
> index
);
2086 return mc
->editbox
.ids
[index
];
2091 int dlg_listbox_index(union control
*ctrl
, void *dlg
)
2093 struct macctrls
*mcs
= dlg
;
2094 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2095 Cell cell
= { 0, 0 };
2098 switch (ctrl
->generic
.type
) {
2100 if (ctrl
->listbox
.height
== 0)
2101 return GetControlValue(mc
->popup
.tbctrl
) - 1;
2103 if (LGetSelect(TRUE
, &cell
, mc
->listbox
.list
))
2109 return GetControlValue(mc
->editbox
.tbbutton
) - 1;
2114 int dlg_listbox_issel(union control
*ctrl
, void *dlg
, int index
)
2116 struct macctrls
*mcs
= dlg
;
2117 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2118 Cell cell
= { 0, 0 };
2121 switch (ctrl
->generic
.type
) {
2123 if (ctrl
->listbox
.height
== 0)
2124 return GetControlValue(mc
->popup
.tbctrl
) - 1 == index
;
2127 return LGetSelect(FALSE
, &cell
, mc
->listbox
.list
);
2130 return GetControlValue(mc
->editbox
.tbbutton
) - 1 == index
;
2135 void dlg_listbox_select(union control
*ctrl
, void *dlg
, int index
)
2137 struct macctrls
*mcs
= dlg
;
2138 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2140 if (mc
== NULL
) return;
2141 switch (ctrl
->generic
.type
) {
2143 if (ctrl
->listbox
.height
== 0)
2144 SetControlValue(mc
->popup
.tbctrl
, index
+ 1);
2147 SetControlValue(mc
->editbox
.tbbutton
, index
+ 1);
2151 static void draglist_move(union macctrl
*mc
, struct macctrls
*mcs
,
2158 short curlength
= 255;
2159 short newlength
= 255;
2162 int index
= dlg_listbox_index(mc
->generic
.ctrl
, mcs
);
2164 #if TARGET_API_MAC_CARBON
2165 GetListDataBounds(mc
->listbox
.list
, &bounds
);
2167 bounds
= (*mc
->listbox
.list
)->dataBounds
;
2171 (index
== 0 && direction
< 0) ||
2172 (index
== bounds
.bottom
-1 && direction
> 0)) {
2177 /* Swap the contents of the selected and target list cells */
2180 LGetCell(current
, &curlength
, cell
, mc
->listbox
.list
);
2181 current
[curlength
] = '\0';
2182 cell
.v
+= direction
;
2183 LGetCell(new, &newlength
, cell
, mc
->listbox
.list
);
2184 new[newlength
] = '\0';
2187 LSetCell(new, newlength
, cell
, mc
->listbox
.list
);
2188 cell
.v
+= direction
;
2189 LSetCell(current
, curlength
, cell
, mc
->listbox
.list
);
2191 /* Move the selection to the target list cell */
2194 LSetSelect(FALSE
, cell
, mc
->listbox
.list
);
2195 cell
.v
+= direction
;
2196 LSetSelect(TRUE
, cell
, mc
->listbox
.list
);
2197 DrawOneControl(mc
->listbox
.tbctrl
);
2199 /* Swap the ids of the list cells */
2201 curid
= mc
->listbox
.ids
[index
];
2202 newid
= mc
->listbox
.ids
[index
+ direction
];
2203 mc
->listbox
.ids
[index
] = newid
;
2204 mc
->listbox
.ids
[index
+ direction
] = curid
;
2206 ctrlevent(mcs
, mc
, EVENT_VALCHANGE
);
2209 static void draglist_up(union macctrl
*mc
, struct macctrls
*mcs
)
2211 draglist_move(mc
, mcs
, -1);
2214 static void draglist_down(union macctrl
*mc
, struct macctrls
*mcs
)
2216 draglist_move(mc
, mcs
, +1);
2223 void dlg_text_set(union control
*ctrl
, void *dlg
, char const *text
)
2225 struct macctrls
*mcs
= dlg
;
2226 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2228 if (mc
== NULL
) return;
2229 if (mac_gestalts
.apprvers
>= 0x100)
2230 SetControlData(mc
->text
.tbctrl
, kControlEntireControl
,
2231 kControlStaticTextTextTag
, strlen(text
), text
);
2232 #if !TARGET_API_MAC_CARBON
2234 TESetText(text
, strlen(text
),
2235 (TEHandle
)(*mc
->text
.tbctrl
)->contrlData
);
2241 * File Selector control
2244 void dlg_filesel_set(union control
*ctrl
, void *dlg
, Filename fn
)
2249 void dlg_filesel_get(union control
*ctrl
, void *dlg
, Filename
*fn
)
2256 * Font Selector control
2259 void dlg_fontsel_set(union control
*ctrl
, void *dlg
, FontSpec fn
)
2264 void dlg_fontsel_get(union control
*ctrl
, void *dlg
, FontSpec
*fn
)
2271 * Printer enumeration
2274 printer_enum
*printer_start_enum(int *nprinters
)
2281 char *printer_get_name(printer_enum
*pe
, int thing
)
2287 void printer_finish_enum(printer_enum
*pe
)
2294 * Colour selection stuff
2297 void dlg_coloursel_start(union control
*ctrl
, void *dlg
,
2298 int r
, int g
, int b
)
2300 struct macctrls
*mcs
= dlg
;
2301 union macctrl
*mc
= findbyctrl(mcs
, ctrl
);
2302 Point where
= {-1, -1}; /* Screen with greatest colour depth */
2305 if (HAVE_COLOR_QD()) {
2306 incolour
.red
= r
* 0x0101;
2307 incolour
.green
= g
* 0x0101;
2308 incolour
.blue
= b
* 0x0101;
2309 mcs
->gotcolour
= GetColor(where
, "\pModify Colour:", &incolour
,
2311 ctrlevent(mcs
, mc
, EVENT_CALLBACK
);
2316 int dlg_coloursel_results(union control
*ctrl
, void *dlg
,
2317 int *r
, int *g
, int *b
)
2319 struct macctrls
*mcs
= dlg
;
2321 if (mcs
->gotcolour
) {
2322 *r
= mcs
->thecolour
.red
>> 8;
2323 *g
= mcs
->thecolour
.green
>> 8;
2324 *b
= mcs
->thecolour
.blue
>> 8;
2332 * c-file-style: "simon"