1 /* $Id: MegaB.c,v 1.1 2002/05/14 23:01:27 dannybackx Exp $ */
2 /*
3 * Copyright 1994 John L. Cwikla
4 *
5 * Permission to use, copy, modify, distribute, and sell this software
6 * and its documentation for any purpose is hereby granted without fee,
7 * provided that the above copyright notice appears in all copies and that
8 * both that copyright notice and this permission notice appear in
9 * supporting documentation, and that the name of John L. Cwikla or
10 * Wolfram Research, Inc not be used in advertising or publicity
11 * pertaining to distribution of the software without specific, written
12 * prior permission. John L. Cwikla and Wolfram Research, Inc make no
13 * representations about the suitability of this software for any
14 * purpose. It is provided "as is" without express or implied warranty.
15 *
16 * John L. Cwikla and Wolfram Research, Inc disclaim all warranties with
17 * regard to this software, including all implied warranties of
18 * merchantability and fitness, in no event shall John L. Cwikla or
19 * Wolfram Research, Inc be liable for any special, indirect or
20 * consequential damages or any damages whatsoever resulting from loss of
21 * use, data or profits, whether in an action of contract, negligence or
22 * other tortious action, arising out of or in connection with the use or
23 * performance of this software.
24 *
25 * Author:
26 * John L. Cwikla
27 * X Programmer
28 * Wolfram Research Inc.
29 *
30 * cwikla@wri.com
31 */
32
33 #include <Xm/XmP.h>
34 #include <Xm/XmosP.h>
35
36 #include <Xm/BaseClassP.h>
37 #include <Xm/DrawP.h>
38 #include <Xm/MenuShellP.h>
39 #include <Xm/MenuUtilP.h>
40 #include <Xm/CascadeB.h>
41 #include <Xm/CascadeBG.h>
42 #include <X11/Xfuncs.h>
43
44 #if HAVE_SOURCE || defined(LESSTIF_VERSION)
45 #include "XmI/TraversalI.h"
46 #endif /* HAVE_SOURCE */
47
48 #include "MegaBP.h"
49
50 #include <stdio.h>
51 #include <ctype.h>
52
53 #define SCROLL_TIME 100
54 #define MINI_SEP_HEIGHT 3
55
56 static XtWidgetClassProc classPartInit(WidgetClass _wc);
57 static XtProc classInit();
58 static XtInitProc initialize(Widget _request, Widget _new, String *_args,
59 Cardinal *_numArg);
60 static XtWidgetProc destroy(Widget _mbw);
61 static void expose(Widget _mbw, XEvent *_event, Region _region);
62 static Boolean setValues(Widget _current, Widget _request, Widget _new, ArgList args, Cardinal *num_args);
63 static void borderHighlight(Widget _mbw);
64 static void borderUnhighlight(Widget _mbw);
65
66 static void getMaxWidthPos(Widget _mbw, int *_maxWidthPos, Dimension *_height);
67 static void drawMiniSeparator(Widget _mbw, Position _y);
68
69 static void enterWidget(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
70 static void leaveWidget(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
71 static void buttonMotion(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
72 static void up(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
73 static void down(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
74 static void buttonUp(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
75 static void buttonDown(Widget _mbw, XEvent *_event, String *_params,
76 Cardinal *_numParms);
77 static void armAndActivate(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
78 static void focusIn(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
79 static void focusOut(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams);
80 static void timedScroll(XtPointer _closure, XtIntervalId *_id);
81 static Boolean cvtStringToMegaButtonMode(Display *_display, XrmValuePtr _args,
82 Cardinal *_numArgs, XrmValuePtr _from, XrmValuePtr _to, XtPointer *_data);
83
84 static void drawShadowedItem(Widget _mbw, int _pos, Boolean _clear);
85 static void drawArrow(Widget _mbw, int _pos, int _direction, Boolean _sensitive);
86 static void clearArrow(Widget _mbw, int _pos);
87 static void scroll(Widget _mbw, int _direction, Boolean _addTimeout, int _delay);
88 static void findGoodShowPos(Widget _mbw);
89
90 static void toggleDrawProc(Widget _mbw, Position _x, Position _y, Boolean _on);
91 static void toggleSpaceProc(Widget _mbw, Dimension *_width, Dimension *_height);
92
93 static void recheckSizesAtPos(Widget _mbw, int _pos);
94
95 static Widget XtGetShell(Widget _w);
96
97 #define CORE(w) (((XmMegaButtonWidget)(w))->core)
98 #define PRIM(w) (((XmMegaButtonWidget)(w))->primitive)
99 #define LABEL(w) (((XmMegaButtonWidget)(w))->label)
100 #define PUSH(w) (((XmMegaButtonWidget)(w))->push_button)
101 #define MB(w) (((XmMegaButtonWidget)(w))->mega_button)
102
103 #define WIDTH(w) (((XmMegaButtonWidget)(w))->core.width)
104 #define HEIGHT(w) (((XmMegaButtonWidget)(w))->core.height)
105
106 #define VIS_COUNT(w) (((XmMegaButtonWidget)(w))->mega_button.visibleItemCount)
107 #define ICOUNT(w) (((XmMegaButtonWidget)(w))->mega_button.itemCount)
108 #define ITEMS(w) (((XmMegaButtonWidget)(w))->mega_button._items)
109 #define EXITEMS(w) (((XmMegaButtonWidget)(w))->mega_button.exitems)
110 #define VIS_POS(w) (((XmMegaButtonWidget)(w))->mega_button.visiblePos)
111 #define FPOS(w) (((XmMegaButtonWidget)(w))->mega_button.firstVisibleItem)
112 #define EL_HEIGHT(w) (((XmMegaButtonWidget)(w))->mega_button.elementHeight)
113 #define YOFFSET(w) (((XmMegaButtonWidget)(w))->mega_button.yOffset)
114 #define XOFFSET(w) (((XmMegaButtonWidget)(w))->mega_button.xOffset)
115 #define HAS_ARROWS(w) (((XmMegaButtonWidget)(w))->mega_button.hasArrows)
116 #define SET_POS(w) (((XmMegaButtonWidget)(w))->mega_button.setPosition)
117 #define COPY_GC(w) (((XmMegaButtonWidget)(w))->mega_button.copyGC)
118 #define TIMER(w) (((XmMegaButtonWidget)(w))->mega_button.timer)
119 #define TDIR(w) (((XmMegaButtonWidget)(w))->mega_button.timedScrollDirection)
120 #define SFOS(w) (((XmMegaButtonWidget)(w))->mega_button.savedFillOnSelect)
121 #define IDELAY(w) (((XmMegaButtonWidget)(w))->mega_button.initialDelay)
122 #define RDELAY(w) (((XmMegaButtonWidget)(w))->mega_button.repeatDelay)
123 #define FAKE_ITEM(w) (((XmMegaButtonWidget)(w))->mega_button.fakeItem)
124 #define CUR_SIZE(w) (((XmMegaButtonWidget)(w))->mega_button.currentSize)
125 #define DATA(w) (((XmMegaButtonWidget)(w))->mega_button.data)
126 #define CB_DATA(w) (((XmMegaButtonWidget)(w))->mega_button.cbData)
127 #define MAX_STRING_POS(w) (((XmMegaButtonWidget)(w))->mega_button.maxStringPos)
128 #define MAX_STRING_WIDTH(w) (((XmMegaButtonWidget)(w))->mega_button.maxStringWidth)
129 #define MODE(w) (((XmMegaButtonWidget)(w))->mega_button.mode)
130 #define TOG_DATA(w) (((XmMegaButtonWidget)(w))->mega_button.toggleData)
131 #define FILL_ON_SELECT(w) (((XmMegaButtonWidget)(w))->mega_button.fillOnSelect)
132 #define SELECT_COLOR(w) (((XmMegaButtonWidget)(w))->mega_button.selectColor)
133 #define SELECT_GC(w) (((XmMegaButtonWidget)(w))->mega_button.selectGC)
134 #define CHUNK_SIZE(w) (((XmMegaButtonWidget)(w))->mega_button.chunkSize)
135 #define VIS_W_OFF(w) (((XmMegaButtonWidget)(w))->mega_button.visibleWhenOff)
136 #define STR_HEIGHT(w) (((XmMegaButtonWidget)(w))->mega_button.stringHeight)
137
138 #define DEFAULT_CHUNK_SIZE 50
139
140 static char traversalTranslations[] =
141 "<Btn1Motion>: BtnMotion() \n\
142 <Enter>: Enter() \n\
143 <Leave>: Leave() \n\
144 <Key>osfHelp:Help() \n\
145 <Unmap>:Unmap()\n\
146 <FocusOut>:FocusOut()\n\
147 <FocusIn>:FocusIn()\n\
148 <Key>osfCancel:MenuEscape()\n\
149 <Key>osfUp: MegaButtonTraverseUp() \n\
150 <Key>osfDown: MegaButtonTraverseDown() \n\
151 <Key>osfLeft:MenuTraverseLeft()\n\
152 <Key>osfRight:MenuTraverseRight()\n\
153 <Key>osfSelect:ArmAndActivate()\n\
154 <Key>osfActivate:ArmAndActivate()\n\
155 ~s ~m ~a <Key>Return:ArmAndActivate()\n\
156 ~s ~m ~a <Key>space:ArmAndActivate()";
157
158 #define TheOffset(field) XtOffset(XmMegaButtonWidget, mega_button.field)
159 static XtResource resources[] =
160 {
161 {XmNitems, XmCItems, XtRPointer, sizeof(XtPointer),
162 TheOffset(exitems), XmRImmediate, (XtPointer)NULL},
163 {XmNitemCount, XmCItemCount, XtRInt, sizeof(int),
164 TheOffset(itemCount), XmRImmediate, (XtPointer)0},
165 {XmNvisibleItemCount, XmCVisibleItemCount, XmRInt, sizeof(int),
166 TheOffset(visibleItemCount), XtRImmediate, (XtPointer)0},
167 {XmNsetPosition, XmCSetPosition, XtRInt, sizeof(int),
168 TheOffset(setPosition), XmRImmediate, (XtPointer)-1},
169 {XmNrepeatDelay, XmCRepeatDelay, XmRInt, sizeof(int),
170 TheOffset(repeatDelay), XmRImmediate, (XtPointer)50},
171 {XmNinitialDelay, XmCInitialDelay, XmRInt, sizeof(int),
172 TheOffset(initialDelay), XmRImmediate, (XtPointer)250},
173 {XmNbuttonMode, XmCButtonMode, XmRMegaButtonMode, sizeof(unsigned char),
174 TheOffset(mode), XmRImmediate, (XtPointer)XmMODE_TOGGLE_BUTTON},
175 {XmNselectColor, XmCSelectColor, XmRPixel, sizeof(Pixel),
176 TheOffset(selectColor), XmRCallProc, (XtPointer)_XmSelectColorDefault},
177 {XmNfillOnSelect, XmCFillOnSelect, XmRBoolean, sizeof(Boolean),
178 TheOffset(fillOnSelect), XmRImmediate, (XtPointer)FALSE},
179 {XmNchunkSize, XmCChunkSize, XmRInt, sizeof(int),
180 TheOffset(chunkSize), XmRImmediate, (XtPointer)DEFAULT_CHUNK_SIZE},
181 {XmNcallbackData, XmCCallbackData, XmRPointer, sizeof(XtPointer),
182 TheOffset(cbData), XmRImmediate, (XtPointer)NULL},
183 {XmNvisibleWhenOff, XmCVisibleWhenOff, XmRBoolean, sizeof(Boolean),
184 TheOffset(visibleWhenOff), XtRImmediate, (XtPointer)FALSE},
185 };
186
187 #undef TheOffset
188
189 static XtActionsRec actions[] =
190 {
191 { "Enter", (XtActionProc) enterWidget },
192 { "Leave", (XtActionProc) leaveWidget },
193 { "BtnMotion", (XtActionProc) buttonMotion },
194 { "MegaButtonTraverseUp", (XtActionProc) up },
195 { "MegaButtonTraverseDown", (XtActionProc) down },
196 { "ArmAndActivate", (XtActionProc) armAndActivate },
197 { "BtnUp", (XtActionProc) buttonUp },
198 { "BtnDown", (XtActionProc) buttonDown},
199 { "FocusIn", (XtActionProc) focusIn },
200 { "FocusOut", (XtActionProc) focusOut},
201
202 {"MenuBtnDown", (XtActionProc)down},
203 {"MenuBtnUp", (XtActionProc)up},
204 {"PulldownBtnDown", (XtActionProc)down},
205 {"PulldownBtnUp", (XtActionProc)up},
206 {"PopupBtnDown", (XtActionProc)down},
207 {"PopupBtnUp", (XtActionProc)up},
208 {"MenuBarBtnDown", (XtActionProc)down},
209 {"MenuBarBtnUp", (XtActionProc)up},
210
211 {"MenuTraverseUp", (XtActionProc)up},
212 {"MenuTraverseDown", (XtActionProc)down},
213 {"MenuFocusIn", (XtActionProc)focusIn },
214 {"MenuFocusOut", (XtActionProc)focusOut },
215 {"MenuUnmap", (XtActionProc)leaveWidget },
216 {"MenuEnter", (XtActionProc)enterWidget},
217
218 }; /* actions */
219
220 static XmBaseClassExtRec megaBBaseClassExtRec =
221 {
222 NULL, /* Next extension */
223 NULLQUARK, /* record type XmQmotif */
224 XmBaseClassExtVersion, /* version */
225 sizeof(XmBaseClassExtRec), /* size */
226 XmInheritInitializePrehook, /* initialize prehook */
227 XmInheritSetValuesPrehook, /* set_values prehook */
228 XmInheritInitializePosthook, /* initialize posthook */
229 XmInheritSetValuesPosthook, /* set_values posthook */
230 XmInheritClass, /* secondary class */
231 XmInheritSecObjectCreate, /* creation proc */
232 XmInheritGetSecResData, /* getSecResData */
233 {0}, /* fast subclass */
234 XmInheritGetValuesPrehook, /* get_values prehook */
235 XmInheritGetValuesPosthook, /* get_values posthook */
236 (XtWidgetClassProc)NULL, /* classPartInitPrehook */
237 (XtWidgetClassProc)NULL, /* classPartInitPosthook*/
238 NULL, /* ext_resources */
239 NULL, /* compiled_ext_resources*/
240 0, /* num_ext_resources */
241 FALSE, /* use_sub_resources */
242 XmInheritWidgetNavigable, /* widgetNavigable */
243 XmInheritFocusChange, /* focusChange */
244 };
245
246 XmPrimitiveClassExtRec _XmMegaBPrimClassExtRec =
247 {
248 NULL,
249 NULLQUARK,
250 XmPrimitiveClassExtVersion,
251 sizeof(XmPrimitiveClassExtRec),
252 XmInheritBaselineProc, /* widget_baseline */
253 XmInheritDisplayRectProc, /* widget_display_rect */
254 (XmWidgetMarginsProc)NULL, /* widget_margins */
255 };
256
257
258 XmMegaButtonClassRec xmMegaButtonClassRec =
259 {
260 {
261 (WidgetClass)&xmPushButtonClassRec, /* superclass */
262 "XmMegaButton", /* class_name */
263 (Cardinal)sizeof(XmMegaButtonRec), /* widget size */
264 (XtProc)classInit, /* class_init */
265 (XtWidgetClassProc)classPartInit, /* class_part_init */
266 (XtEnum)FALSE, /* class_inited */
267 (XtInitProc)initialize, /* initialize */
268 (XtArgsProc)NULL, /* init_hook */
269 XtInheritRealize, /* realize */
270 (XtActionList)actions, /* actions */
271 (Cardinal)XtNumber(actions), /* num_actions */
272 (XtResourceList)resources, /* resources */
273 (Cardinal)XtNumber(resources), /* num_resources */
274 NULLQUARK, /* xrm_class */
275 TRUE, /* compress_motion */
276 (XtEnum)FALSE, /* compress_exposur */
277 TRUE, /* compress enterleave */
278 FALSE, /* visibility_interest */
279 (XtWidgetProc)destroy, /* destroy */
280 (XtWidgetProc)XtInheritResize,
281 (XtExposeProc)expose,
282 (XtSetValuesFunc)setValues, /* set_values */
283 (XtArgsFunc)NULL, /* set_values_hook */
284 XtInheritSetValuesAlmost, /* set_values_almost */
285 (XtArgsProc)NULL, /* get_values_hook */
286 NULL, /* accept_focus */
287 XtVersion, /* version */
288 (XtPointer)NULL, /* callback_private */
289 XtInheritTranslations,
290 (XtGeometryHandler)NULL, /* query_geometry */
291 XtInheritDisplayAccelerator, /* display_accelerator */
292 (XtPointer)&megaBBaseClassExtRec, /* extension */
293 },
294 { /* xmPrimitiveClass */
295 (XtWidgetProc)borderHighlight,
296 (XtWidgetProc)borderUnhighlight,
297 XtInheritTranslations,
298 (XtActionProc)armAndActivate,
299 NULL,
300 0,
301 (XtPointer)&_XmMegaBPrimClassExtRec,
302 },
303 { /* xmLabelClass */
304 (XtWidgetProc) XmInheritSetOverrideCallback,
305 NULL,
306 NULL,
307 NULL,
308 },
309 { /* xmPushButtonClass */
310 (XtPointer)NULL,
311 },
312 {
313 XmInheritMegaButtonToggleSpaceProc,
314 XmInheritMegaButtonToggleDrawProc,
315 }
316 };
317
318 WidgetClass xmMegaButtonWidgetClass = (WidgetClass)&xmMegaButtonClassRec;
319
320
classPartInit(WidgetClass _wc)321 static XtWidgetClassProc classPartInit(WidgetClass _wc)
322 {
323 XmMegaButtonWidgetClass mbwc;
324
325 _XmFastSubclassInit(_wc, (XmPUSH_BUTTON_BIT | XmLABEL_BIT |
326 XmPRIMITIVE_BIT));
327
328 mbwc = (XmMegaButtonWidgetClass)_wc;
329 if (mbwc->mega_button_class.toggleSpaceProc == XmInheritMegaButtonToggleSpaceProc)
330 mbwc->mega_button_class.toggleSpaceProc = toggleSpaceProc;
331 if (mbwc->mega_button_class.toggleDrawProc == XmInheritMegaButtonToggleDrawProc)
332 mbwc->mega_button_class.toggleDrawProc = toggleDrawProc;
333 return (XtWidgetClassProc)NULL;
334 }
335
classInit()336 static XtProc classInit()
337 {
338 xmMegaButtonClassRec.label_class.translations = (String)XtParseTranslationTable(traversalTranslations);
339
340 XtSetTypeConverter(XtRString, XmRMegaButtonMode, cvtStringToMegaButtonMode,
341 (XtConvertArgList)NULL, 0,
342 XtCacheAll, (XtDestructor)NULL);
343
344 return (XtProc)NULL;
345 }
346
initialize(Widget _request,Widget _new,String * _args,Cardinal * _numArgs)347 static XtInitProc initialize(Widget _request, Widget _new, String *_args, Cardinal *_numArgs)
348 {
349 int i;
350 XmString xmstring;
351 XGCValues gcValues;
352 Dimension width;
353
354 VIS_POS(_new) = -1;
355
356 FPOS(_new) = 0;
357 TOG_DATA(_new) = NULL;
358 if ((MODE(_new) == XmMODE_TOGGLE_BUTTON) && (SET_POS(_new) > (ICOUNT(_new)-1)))
359 SET_POS(_new) = ICOUNT(_new) - 1;
360
361 if (CHUNK_SIZE(_new) < 1)
362 CHUNK_SIZE(_new) = DEFAULT_CHUNK_SIZE;
363
364 if (ICOUNT(_new) == 0)
365 {
366 if (LABEL(_new)._label == (_XmString) XmUNSPECIFIED)
367 {
368 xmstring = _XmOSGetLocalizedString ((char *) NULL, /* reserved */
369 (Widget)_new,
370 XmNlabelString,
371 "\0");
372
373 LABEL(_new)._label = _XmStringCreate(xmstring);
374 }
375 else
376 if (LABEL(_new)._label == NULL)
377 {
378 xmstring = _XmOSGetLocalizedString ((char *) NULL, /* reserved */
379 (Widget)_new,
380 XmNlabelString,
381 CORE(_new).name);
382
383 LABEL(_new)._label = _XmStringCreate(xmstring);
384 }
385 ICOUNT(_new) = 1;
386 ITEMS(_new) = XtNew(_XmString);
387 ITEMS(_new)[0] = LABEL(_new)._label;
388 DATA(_new) = XtNew(XtPointer);
389 DATA(_new)[0] = (XtPointer)NULL;
390 FAKE_ITEM(_new) = TRUE;
391 }
392 else
393 {
394 ITEMS(_new) = (_XmString *)XtMalloc(sizeof(_XmString) * ICOUNT(_new));
395 DATA(_new) = (XtPointer)XtCalloc(ICOUNT(_new), sizeof(XtPointer));
396 if (CB_DATA(_new) != NULL)
397 for(i=0;i<ICOUNT(_new);i++)
398 {
399 ITEMS(_new)[i] = _XmStringCreate(EXITEMS(_new)[i]);
400 DATA(_new)[i] = CB_DATA(_new)[i];
401 }
402 else
403 for(i=0;i<ICOUNT(_new);i++)
404 {
405 ITEMS(_new)[i] = _XmStringCreate(EXITEMS(_new)[i]);
406 DATA(_new)[i] = NULL;
407 }
408
409 FAKE_ITEM(_new) = FALSE;
410 }
411
412 CUR_SIZE(_new) = ICOUNT(_new);
413
414 getMaxWidthPos(_new, &MAX_STRING_POS(_new), &EL_HEIGHT(_new));
415 _XmStringExtent(LABEL(_new).font, ITEMS(_new)[0], &width, &STR_HEIGHT(_new));
416
417
418 EL_HEIGHT(_new) += 2 * PRIM(_new).shadow_thickness;
419 HEIGHT(_new) = EL_HEIGHT(_new);
420
421 LABEL(_new)._label = ITEMS(_new)[MAX_STRING_POS(_new)];
422 _XmCalcLabelDimensions((Widget)_new);
423 MAX_STRING_WIDTH(_new) = LABEL(_new).TextRect.width;
424 WIDTH(_new) = 0;
425 (*xmLabelWidgetClass->core_class.resize) ((Widget)_new);
426
427 YOFFSET(_new) = LABEL(_new).TextRect.y;
428 XOFFSET(_new) = LABEL(_new).TextRect.x;
429
430 if ( (MODE(_new) == XmMODE_TOGGLE_BUTTON) && ( ((XmMegaButtonWidgetClass)XtClass(_new))->mega_button_class.toggleSpaceProc))
431 (( (XmMegaButtonWidgetClass)XtClass(_new))->mega_button_class.toggleSpaceProc)(_new, &WIDTH(_new), &EL_HEIGHT(_new));
432
433 if (VIS_COUNT(_new) == 0)
434 {
435 Dimension dheight;
436 int vcount;
437
438 dheight = DisplayHeight(XtDisplay(_new), DefaultScreen(XtDisplay(_new)));
439
440 vcount = dheight/EL_HEIGHT(_new) - 4;
441 if (vcount <=3)
442 vcount = 3;
443
444 VIS_COUNT(_new) = vcount;
445 }
446
447 HAS_ARROWS(_new) = ICOUNT(_new) > VIS_COUNT(_new);
448
449 if (HAS_ARROWS(_new))
450 HEIGHT(_new) =
451 HEIGHT(_new) * (VIS_COUNT(_new) + 2) + (2 * MINI_SEP_HEIGHT);
452 else
453 HEIGHT(_new) *= ICOUNT(_new);
454
455 gcValues.foreground = CORE(_new).background_pixel;
456 COPY_GC(_new) = XtGetGC((Widget)_new, GCForeground, &gcValues);
457
458 gcValues.foreground = FILL_ON_SELECT(_new) ? SELECT_COLOR(_new) : CORE(_new).background_pixel;
459
460 SELECT_GC(_new) = XtGetGC((Widget)_new, GCForeground, &gcValues);
461 TIMER(_new) = -1;
462
463 return (XtInitProc)NULL;
464 }
465
destroy(Widget _mbw)466 static XtWidgetProc destroy(Widget _mbw)
467 {
468 register int i;
469
470 XtReleaseGC((Widget)_mbw, COPY_GC(_mbw));
471 XtReleaseGC((Widget)_mbw, SELECT_GC(_mbw));
472
473 for(i=0;i<ICOUNT(_mbw);i++) {
474 if(ITEMS(_mbw)[i] != LABEL(_mbw)._label)
475 _XmStringFree(ITEMS(_mbw)[i]);
476 }
477
478 XtFree((char *)ITEMS(_mbw));
479 XtFree((char *)DATA(_mbw));
480
481 return (XtWidgetProc)NULL;
482 }
483
expose(Widget _mbw,XEvent * _event,Region _region)484 static void expose(Widget _mbw, XEvent *_event, Region _region)
485 {
486 GC gc;
487 int i, first;
488 Position y;
489
490 if (_event && _XmIsEventUnique(_event ))
491 return; /* from _XmFastExpose... */
492
493 findGoodShowPos(_mbw);
494
495 gc = XtIsSensitive(_mbw) ? LABEL(_mbw).normal_GC : LABEL(_mbw).insensitive_GC;
496
497 first = FPOS(_mbw);
498 y = 0;
499 if (HAS_ARROWS(_mbw))
500 {
501 drawArrow(_mbw, 0, XmARROW_UP, (FPOS(_mbw) != 0));
502 y += EL_HEIGHT(_mbw);
503 drawMiniSeparator(_mbw, EL_HEIGHT(_mbw));
504 y += MINI_SEP_HEIGHT;
505 }
506
507 y += YOFFSET(_mbw);
508 LABEL(_mbw).TextRect.x = XOFFSET(_mbw);
509
510 for(i=0;(i<VIS_COUNT(_mbw)) && ((first + i) < ICOUNT(_mbw)); i++)
511 {
512 LABEL(_mbw)._label = ITEMS(_mbw)[first+i];
513 _XmCalcLabelDimensions((Widget)_mbw);
514
515 LABEL(_mbw).TextRect.y = y;
516
517 (*xmLabelWidgetClass->core_class.expose) ((Widget)_mbw, _event, _region);
518
519 if ( (MODE(_mbw) == XmMODE_TOGGLE_BUTTON) && ( ((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc))
520 {
521 if ((first + i) == SET_POS(_mbw))
522 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)(_mbw, LABEL(_mbw).TextRect.x, y, TRUE);
523 else
524 if (VIS_W_OFF(_mbw))
525 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)(_mbw, LABEL(_mbw).TextRect.x, y, FALSE);
526 }
527
528 y += EL_HEIGHT(_mbw);
529 }
530
531 y -= YOFFSET(_mbw);
532
533 if (HAS_ARROWS(_mbw))
534 {
535 drawMiniSeparator(_mbw, y);
536 y += MINI_SEP_HEIGHT;
537 drawArrow(_mbw, VIS_COUNT(_mbw)+1, XmARROW_DOWN, ((ICOUNT(_mbw))-FPOS(_mbw)) > VIS_COUNT(_mbw));
538 }
539
540 /* drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE); */
541 }
542
setValues(Widget _current,Widget _request,Widget _new,ArgList args,Cardinal * num_args)543 static Boolean setValues( Widget _current, Widget _request, Widget _new, ArgList args, Cardinal *num_args)
544 {
545 return FALSE;
546 }
547
getMaxWidthPos(Widget _mbw,int * _maxWidthPos,Dimension * _height)548 static void getMaxWidthPos(Widget _mbw, int *_maxWidthPos, Dimension *_height)
549 {
550 int first, i;
551 Dimension maxHeight, maxWidth;
552 int mwp;
553
554 if (ICOUNT(_mbw) == 0)
555 {
556 *_maxWidthPos = 0;
557 *_height = 1;
558 return;
559 }
560
561 first = FPOS(_mbw);
562 mwp = 0;
563 maxHeight = 1;
564 maxWidth = 1;
565 for(i=0; (first + i) < ICOUNT(_mbw); i++)
566 {
567 LABEL(_mbw)._label = ITEMS(_mbw)[first+i];
568 _XmCalcLabelDimensions((Widget)_mbw);
569
570 if (LABEL(_mbw).TextRect.width > maxWidth)
571 {
572 maxWidth = LABEL(_mbw).TextRect.width;
573 mwp = i;
574 }
575
576 if (LABEL(_mbw).TextRect.height > maxHeight)
577 maxHeight = LABEL(_mbw).TextRect.height;
578 }
579
580 *_maxWidthPos = mwp;
581 *_height = maxHeight;
582 }
583
584
drawShadowedItem(Widget _mbw,int _pos,Boolean _clear)585 static void drawShadowedItem(Widget _mbw, int _pos, Boolean _clear)
586 {
587 Position y;
588
589
590 if ( (_pos < 0) || (HAS_ARROWS(_mbw) && (_pos > (VIS_COUNT(_mbw)+1))) ||
591 (!HAS_ARROWS(_mbw) && (_pos >= VIS_COUNT(_mbw)))
592 )
593 return;
594
595 y = 0;
596 if (HAS_ARROWS(_mbw))
597 {
598 if (_pos > 0)
599 y += MINI_SEP_HEIGHT;
600
601 if (_pos > VIS_COUNT(_mbw) )
602 y += MINI_SEP_HEIGHT;
603 }
604
605 y += (_pos * EL_HEIGHT(_mbw));
606
607 if (_clear)
608 {
609 _XmClearBorder(XtDisplay((Widget)_mbw), XtWindow((Widget)_mbw),
610 0, y, WIDTH(_mbw), EL_HEIGHT(_mbw),
611 PRIM(_mbw).shadow_thickness);
612 }
613 else
614 {
615 _XmDrawShadows(XtDisplay((Widget)_mbw), XtWindow((Widget)_mbw),
616 PRIM(_mbw).top_shadow_GC,
617 PRIM(_mbw).bottom_shadow_GC,
618 0, y, WIDTH(_mbw), EL_HEIGHT(_mbw),
619 PRIM(_mbw).shadow_thickness,
620 XmSHADOW_OUT);
621 }
622 }
623
clearArrow(Widget _mbw,int _pos)624 static void clearArrow(Widget _mbw, int _pos)
625 {
626 Position y = 0;
627 if (HAS_ARROWS(_mbw))
628 {
629 if (_pos > 0)
630 y += MINI_SEP_HEIGHT;
631
632 if (_pos > VIS_COUNT(_mbw) )
633 y += MINI_SEP_HEIGHT;
634 }
635
636 y += (_pos * EL_HEIGHT(_mbw));
637
638 XClearArea(XtDisplay(_mbw), XtWindow(_mbw),
639 PRIM(_mbw).shadow_thickness, y + PRIM(_mbw).shadow_thickness,
640 WIDTH(_mbw) - 2 * PRIM(_mbw).shadow_thickness,
641 EL_HEIGHT(_mbw) - 2 * PRIM(_mbw).shadow_thickness, FALSE);
642 }
643
yToPos(Widget _mbw,Position _y)644 static int yToPos(Widget _mbw, Position _y)
645 {
646 Dimension topOffset, bottomOffset;
647
648 if ((_y >= 0) && HAS_ARROWS(_mbw))
649 {
650 if ((Dimension)_y <= EL_HEIGHT(_mbw))
651 return 0;
652
653 topOffset = EL_HEIGHT(_mbw) + MINI_SEP_HEIGHT;
654 if ((Dimension)_y <= topOffset)
655 return 0;
656
657 bottomOffset = HEIGHT(_mbw) - EL_HEIGHT(_mbw);
658 if ((Dimension)_y >= bottomOffset)
659 return VIS_COUNT(_mbw)+1;
660
661 bottomOffset -= MINI_SEP_HEIGHT;
662
663 if ((Dimension)_y >= bottomOffset)
664 return VIS_COUNT(_mbw);
665
666 _y -= MINI_SEP_HEIGHT;
667 }
668
669 return _y/EL_HEIGHT(_mbw);
670 }
671
672
enterWidget(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)673 static void enterWidget(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
674 {
675 if (ICOUNT(_mbw) == 0)
676 return;
677
678 XtCallActionProc((Widget)_mbw, "PrimitiveEnter", _event, _params, *_numParams);
679 if ( LABEL(_mbw).menu_type != XmWORK_AREA )
680 {
681 if (_XmGetInDragMode((Widget)_mbw))
682 {
683 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
684 VIS_POS(_mbw) = yToPos(_mbw, _event->xbutton.y);
685 drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE);
686
687 if (HAS_ARROWS(_mbw))
688 {
689 if (VIS_POS(_mbw) == VIS_COUNT(_mbw)+1)
690 {
691 TDIR(_mbw) = XmTRAVERSE_DOWN;
692 TIMER(_mbw) = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)_mbw),
693 (unsigned long)IDELAY(_mbw),
694 timedScroll, (XtPointer)_mbw);
695 }
696 else
697 if (VIS_POS(_mbw) == 0)
698 {
699 TDIR(_mbw) = XmTRAVERSE_UP;
700 TIMER(_mbw) = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)_mbw),
701 (unsigned long)IDELAY(_mbw),
702 timedScroll, (XtPointer)_mbw);
703 }
704 }
705 }
706 }
707 }
708
leaveWidget(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)709 static void leaveWidget(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
710 {
711 if (ICOUNT(_mbw) == 0)
712 return;
713
714 XtCallActionProc((Widget)_mbw, "PrimitiveLeave", _event, _params, *_numParams);
715 if ( LABEL(_mbw).menu_type != XmWORK_AREA )
716 {
717 /* if ( _XmGetInDragMode((Widget)_mbw) ) */
718
719 /* drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE); */
720
721 if (TIMER(_mbw) != -1)
722 {
723 XtRemoveTimeOut(TIMER(_mbw));
724 TIMER(_mbw) = -1;
725 }
726 }
727 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
728 }
729
buttonMotion(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)730 static void buttonMotion(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
731 {
732 if (ICOUNT(_mbw) == 0)
733 return;
734
735
736 if ( LABEL(_mbw).menu_type != XmWORK_AREA )
737 {
738 int pos = yToPos(_mbw, _event->xmotion.y);
739 if (pos != VIS_POS(_mbw))
740 {
741 if (TIMER(_mbw) != -1)
742 {
743 XtRemoveTimeOut(TIMER(_mbw));
744 TIMER(_mbw) = -1;
745 }
746 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
747 drawShadowedItem(_mbw, pos, FALSE);
748 VIS_POS(_mbw) = pos;
749
750 if (HAS_ARROWS(_mbw))
751 {
752 if (VIS_POS(_mbw) == VIS_COUNT(_mbw)+1)
753 scroll(_mbw, XmTRAVERSE_DOWN, TRUE, IDELAY(_mbw));
754 else
755 if (VIS_POS(_mbw) == 0)
756 scroll(_mbw, XmTRAVERSE_UP, TRUE, IDELAY(_mbw));
757 }
758 _XmSetInDragMode((Widget)_mbw, TRUE);
759 }
760 }
761 }
762
up(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)763 static void up(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
764 {
765 int vpos;
766
767 if (ICOUNT(_mbw) == 0)
768 return;
769
770 if (LABEL(_mbw).menu_type != XmWORK_AREA )
771 {
772 if (!_XmGetInDragMode((Widget)_mbw))
773 {
774 vpos = VIS_POS(_mbw);
775 vpos--;
776
777 if ((vpos == -1) && (FPOS(_mbw) == 0))
778 {
779 CompositeWidget parent = (CompositeWidget)XtParent(_mbw);
780 if (parent->composite.num_children > 1)
781 {
782 XtCallActionProc((Widget)_mbw, "PrimitiveTraverseUp", _event, _params, *_numParams);
783 return;
784 }
785 }
786
787 if (HAS_ARROWS(_mbw) && (vpos <= 0))
788 {
789 if (vpos == 0)
790 {
791 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
792 drawShadowedItem(_mbw, vpos, FALSE);
793 }
794 scroll(_mbw, XmTRAVERSE_UP, FALSE, 0);
795 VIS_POS(_mbw) = 0;
796 }
797 else
798 {
799 if (!HAS_ARROWS(_mbw) && (vpos == -1))
800 vpos = ICOUNT(_mbw)-1;
801
802 if (vpos != VIS_POS(_mbw))
803 {
804 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
805 drawShadowedItem(_mbw, vpos, FALSE);
806 VIS_POS(_mbw) = vpos;
807 }
808 }
809
810 _XmRecordEvent(_event);
811 }
812 }
813
814 }
815
down(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)816 static void down(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
817 {
818 int vpos;
819
820 if (ICOUNT(_mbw) == 0)
821 return;
822
823 if (LABEL(_mbw).menu_type != XmWORK_AREA )
824 {
825 if (!_XmGetInDragMode((Widget)_mbw))
826 {
827 vpos = VIS_POS(_mbw);
828 vpos++;
829
830 _XmRecordEvent(_event);
831
832 if (HAS_ARROWS(_mbw) && (vpos >= (VIS_COUNT(_mbw) + 1)))
833 {
834 if (VIS_POS(_mbw) != (VIS_COUNT(_mbw)+1))
835 {
836 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
837 drawShadowedItem(_mbw, vpos, FALSE);
838 }
839 else
840 if (FPOS(_mbw) >= (ICOUNT(_mbw)-VIS_COUNT(_mbw)))
841 {
842 CompositeWidget parent = (CompositeWidget)XtParent(_mbw);
843 if (parent->composite.num_children > 1)
844 {
845 XtCallActionProc((Widget)_mbw, "PrimitiveTraverseDown", _event, _params, *_numParams);
846 return;
847 }
848 }
849
850 scroll(_mbw, XmTRAVERSE_DOWN, FALSE, 0);
851 VIS_POS(_mbw) = VIS_COUNT(_mbw) + 1;
852 }
853 else
854 {
855 if (!HAS_ARROWS(_mbw))
856 {
857 if (vpos == ICOUNT(_mbw))
858 {
859 CompositeWidget parent = (CompositeWidget)XtParent(_mbw);
860 if (parent->composite.num_children > 1)
861 {
862 XtCallActionProc((Widget)_mbw, "PrimitiveTraverseDown", _event, _params, *_numParams);
863 return;
864 }
865 else
866 vpos = 0;
867 }
868 }
869
870 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
871 drawShadowedItem(_mbw, vpos, FALSE);
872 VIS_POS(_mbw) = vpos;
873 }
874 }
875 }
876
877 }
878
buttonUp(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)879 static void buttonUp(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
880 {
881 XmMegaButtonCallbackStruct mtbcs;
882 Widget parent, shell;
883 Boolean validButton;
884 Boolean poppedUp;
885 Boolean isMenuPane;
886
887 if (TIMER(_mbw) != -1)
888 {
889 XtRemoveTimeOut(TIMER(_mbw));
890 TIMER(_mbw) = -1;
891 }
892
893 if (ICOUNT(_mbw) == 0)
894 return;
895
896 isMenuPane = (LABEL(_mbw).menu_type == XmMENU_PULLDOWN) || (LABEL(_mbw).menu_type == XmMENU_POPUP);
897 shell = XtGetShell((Widget)_mbw);
898 parent = XtParent(_mbw);
899
900 if (_event && (_event->type == ButtonRelease))
901 {
902 (* xmLabelClassRec.label_class.menuProcs) (XmMENU_BUTTON, parent, NULL, _event, &validButton);
903 if (!validButton)
904 return;
905
906 VIS_POS(_mbw) = yToPos(_mbw, _event->xbutton.y);
907 }
908
909 if (HAS_ARROWS(_mbw) && !_XmGetInDragMode((Widget)_mbw))
910 {
911 if (VIS_POS(_mbw) == 0)
912 {
913 _XmRecordEvent(_event);
914 return;
915 }
916 else
917 if (VIS_POS(_mbw) == (VIS_COUNT(_mbw)+1))
918 {
919 _XmRecordEvent(_event);
920 return;
921 }
922 }
923
924 if (isMenuPane && !XmIsMenuShell(shell))
925 (* xmLabelClassRec.label_class.menuProcs) (XmMENU_POPDOWN, (Widget) _mbw, NULL, _event, &poppedUp);
926 else
927 (* xmLabelClassRec.label_class.menuProcs) (XmMENU_BUTTON_POPDOWN, (Widget) _mbw , NULL,
928 _event, &poppedUp);
929
930 _XmRecordEvent(_event);
931
932 if (poppedUp)
933 return;
934
935 mtbcs.reason = XmCR_ACTIVATE;
936 mtbcs.event = _event;
937 if (HAS_ARROWS(_mbw))
938 {
939 if ((VIS_POS(_mbw) == 0) || (VIS_POS(_mbw) == (VIS_COUNT(_mbw)+1)))
940 return;
941
942 mtbcs.pos = FPOS(_mbw) + VIS_POS(_mbw) - 1;
943
944 }
945 else
946 mtbcs.pos = VIS_POS(_mbw);
947 mtbcs.callbackValue = DATA(_mbw)[mtbcs.pos];
948 mtbcs.string = _XmStringCreateExternal(LABEL(_mbw).font, ITEMS(_mbw)[mtbcs.pos]);
949
950 SET_POS(_mbw) = mtbcs.pos;
951
952 #if 0
953 if (XmIsRowColumn(parent))
954 (* xmLabelClassRec.label_class.menuProcs) (XmMENU_CALLBACK, parent, FALSE, _mbw, (XtPointer)&mtbcs);
955 else
956 #endif
957 XtCallCallbackList((Widget)_mbw, PUSH(_mbw).activate_callback, &mtbcs);
958
959 _XmSetInDragMode((Widget)_mbw, False);
960 }
961
buttonDown(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParms)962 static void buttonDown(Widget _mbw, XEvent *_event, String *_params,
963 Cardinal *_numParms)
964 {
965 ShellWidget popupShell;
966 int validButton, pos = 0;
967 Widget child;
968
969 if (ICOUNT(_mbw) == 0)
970 return;
971
972 XAllowEvents(XtDisplay(_mbw), SyncPointer, CurrentTime);
973
974 if (_event && (_event->type == ButtonPress))
975 {
976 (* xmLabelClassRec.label_class.menuProcs) (XmMENU_BUTTON, XtParent(_mbw), NULL, _event, &validButton);
977 if (!validButton)
978 return;
979
980 pos = yToPos(_mbw, _event->xbutton.y);
981 }
982
983 if (HAS_ARROWS(_mbw) && !_XmGetInDragMode((Widget)_mbw))
984 {
985 if (pos == 0)
986 {
987 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
988 VIS_POS(_mbw) = pos;
989 drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE);
990 _XmRecordEvent(_event);
991 scroll(_mbw, XmTRAVERSE_UP, TRUE, IDELAY(_mbw));
992 return;
993 }
994 else
995 if (pos == (VIS_COUNT(_mbw)+1))
996 {
997 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
998 VIS_POS(_mbw) = pos;
999 drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE);
1000 _XmRecordEvent(_event);
1001 scroll(_mbw, XmTRAVERSE_DOWN, TRUE, IDELAY(_mbw));
1002 return;
1003 }
1004 }
1005
1006 VIS_POS(_mbw) = pos;
1007
1008 _XmSetInDragMode((Widget)_mbw, TRUE);
1009
1010 popupShell = (ShellWidget)_XmGetRC_PopupPosted(XtParent(_mbw));
1011 if (popupShell)
1012 {
1013 if (popupShell->shell.popped_up)
1014 (* xmLabelClassRec.label_class.menuProcs)(XmMENU_SHELL_POPDOWN, (Widget)popupShell, NULL, _event, NULL);
1015
1016 child = ((XmManagerWidget)XtParent(_mbw))->manager.active_child;
1017 if (child && (XmIsCascadeButton(child) || XmIsCascadeButtonGadget(child)))
1018 XmCascadeButtonHighlight (child, FALSE);
1019 }
1020
1021 XmProcessTraversal( (Widget)_mbw, XmTRAVERSE_CURRENT);
1022
1023 _XmSetInDragMode((Widget)_mbw, FALSE);
1024
1025 _XmRecordEvent(_event);
1026 }
1027
armAndActivate(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)1028 static void armAndActivate(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
1029 {
1030 XmMegaButtonCallbackStruct mtbcs;
1031
1032 if (ICOUNT(_mbw) == 0)
1033 return;
1034
1035 mtbcs.reason = XmCR_ACTIVATE;
1036 mtbcs.event = _event;
1037 if (HAS_ARROWS(_mbw))
1038 {
1039 if ((VIS_POS(_mbw) == 0) || (VIS_POS(_mbw) == (VIS_COUNT(_mbw)+1)))
1040 return;
1041
1042 mtbcs.pos = FPOS(_mbw) + VIS_POS(_mbw) - 1;
1043
1044 }
1045 else
1046 mtbcs.pos = VIS_POS(_mbw);
1047 mtbcs.callbackValue = DATA(_mbw)[mtbcs.pos];
1048 mtbcs.string = _XmStringCreateExternal(LABEL(_mbw).font, ITEMS(_mbw)[mtbcs.pos]);
1049
1050 SET_POS(_mbw) = mtbcs.pos;
1051
1052 XFlush(XtDisplay(_mbw));
1053
1054 XtCallCallbackList((Widget)_mbw, PUSH(_mbw).activate_callback, &mtbcs);
1055 }
1056
XtGetShell(Widget _w)1057 static Widget XtGetShell(Widget _w)
1058 {
1059 Widget temp;
1060
1061 temp = _w;
1062 while(temp && !XtIsSubclass(temp, shellWidgetClass))
1063 temp = XtParent(temp);
1064
1065 return temp;
1066 }
1067
1068 #if !HAVE_SOURCE && !defined(LESSTIF_VERSION)
1069
1070 struct _XmFocusDataRec
1071 {
1072 Widget not_used;
1073 Widget not_used_2;
1074 Widget old_focus_item;
1075 };
1076
1077 #endif /* HAVE_SOURCE */
1078
1079 /*
1080 ** This is a tad hackish. The general idea is that there is no way to tell which
1081 ** directory the focusIn event came from if we are in a menu. So get the
1082 ** focusData which has the last widget to have focus. Use this as an index
1083 ** into the RowCol's children, and go from there.
1084 */
1085
focusIn(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)1086 static void focusIn(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
1087 {
1088 int labelCount;
1089 Widget oldFocus;
1090 CompositeWidget parent;
1091 XmFocusData focusData;
1092 WidgetList children;
1093 int myI, oldI, i;
1094
1095 VIS_POS(_mbw) = 0;
1096 if (ICOUNT(_mbw) == 0)
1097 return;
1098
1099 focusData = _XmGetFocusData((Widget)_mbw);
1100
1101 if (focusData && focusData->old_focus_item)
1102 {
1103 oldFocus = focusData->old_focus_item;
1104 parent = (CompositeWidget)XtParent(_mbw);
1105
1106 children = parent->composite.children;
1107 myI = -1;
1108 oldI = -1;
1109 labelCount = 0;
1110 for(i=0;(i<parent->composite.num_children);i++)
1111 {
1112 if (children[i] == (Widget)_mbw)
1113 myI = i;
1114 else
1115 if (children[i] == oldFocus)
1116 oldI = i;
1117 else
1118 if (XmIsLabel(children[i]))
1119 labelCount++;
1120
1121 if ((myI != -1) && (oldI != -1))
1122 break;
1123 }
1124
1125 if ( (oldI != -1) && ((myI < oldI) ||
1126 ((myI > oldI) && labelCount)))
1127 VIS_POS(_mbw) = (HAS_ARROWS(_mbw) ? VIS_COUNT(_mbw) + 1 : ICOUNT(_mbw)-1);
1128 }
1129
1130
1131
1132 drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE);
1133 }
1134
focusOut(Widget _mbw,XEvent * _event,String * _params,Cardinal * _numParams)1135 static void focusOut(Widget _mbw, XEvent *_event, String *_params, Cardinal *_numParams)
1136 {
1137 if (ICOUNT(_mbw) == 0)
1138 return;
1139
1140 if (TIMER(_mbw) != -1)
1141 {
1142 XtRemoveTimeOut(TIMER(_mbw));
1143 TIMER(_mbw) = -1;
1144 }
1145
1146 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
1147 VIS_POS(_mbw) = 0;
1148 }
1149
borderHighlight(Widget _mbw)1150 static void borderHighlight(Widget _mbw)
1151 {
1152 if (ICOUNT(_mbw) == 0)
1153 return;
1154
1155
1156 if ((LABEL(_mbw).menu_type == XmMENU_PULLDOWN) || (LABEL(_mbw).menu_type == XmMENU_POPUP))
1157 {
1158 drawShadowedItem(_mbw, VIS_POS(_mbw), FALSE);
1159 }
1160 }
1161
borderUnhighlight(Widget _mbw)1162 static void borderUnhighlight(Widget _mbw)
1163 {
1164 if (ICOUNT(_mbw) == 0)
1165 return;
1166
1167
1168 if ((LABEL(_mbw).menu_type == XmMENU_PULLDOWN) || (LABEL(_mbw).menu_type == XmMENU_POPUP))
1169 drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE);
1170 }
1171
drawMiniSeparator(Widget _mbw,Position _y)1172 static void drawMiniSeparator(Widget _mbw, Position _y)
1173 {
1174 int i, firstHalf, secondHalf;
1175
1176 firstHalf = MINI_SEP_HEIGHT/2;
1177 secondHalf = firstHalf;
1178
1179 if (MINI_SEP_HEIGHT % 2)
1180 secondHalf++;
1181
1182 for(i=secondHalf;i<MINI_SEP_HEIGHT;i++)
1183 XDrawLine(XtDisplay(_mbw), XtWindow(_mbw), PRIM(_mbw).top_shadow_GC,
1184 0, _y+i, WIDTH(_mbw), _y+i);
1185
1186 for(i=0;i<firstHalf;i++)
1187 XDrawLine(XtDisplay(_mbw), XtWindow(_mbw), PRIM(_mbw).bottom_shadow_GC,
1188 0, _y+i, WIDTH(_mbw), _y+i);
1189 }
1190
1191
drawArrow(Widget _mbw,int _pos,int _direction,Boolean _sensitive)1192 static void drawArrow(Widget _mbw, int _pos, int _direction, Boolean _sensitive)
1193 {
1194 Dimension arrowWidth;
1195 Position y = 0;
1196
1197 if (HAS_ARROWS(_mbw))
1198 {
1199 if (_pos > 0)
1200 y += MINI_SEP_HEIGHT;
1201
1202 if (_pos > VIS_COUNT(_mbw) )
1203 y += MINI_SEP_HEIGHT;
1204 }
1205
1206 y += (_pos * EL_HEIGHT(_mbw));
1207
1208
1209 arrowWidth = WIDTH(_mbw)/5;
1210
1211 _XmDrawArrow(XtDisplay((Widget)(_mbw)),
1212 XtWindow ((Widget)(_mbw)),
1213 _sensitive ? PRIM(_mbw).top_shadow_GC : PRIM(_mbw).bottom_shadow_GC,
1214 _sensitive ? PRIM(_mbw).bottom_shadow_GC : PRIM(_mbw).top_shadow_GC,
1215 _sensitive ? COPY_GC(_mbw) : LABEL(_mbw).insensitive_GC,
1216 WIDTH(_mbw)/2 - arrowWidth/2,
1217 y + PRIM(_mbw).shadow_thickness,
1218 arrowWidth,
1219 EL_HEIGHT(_mbw) - 2 * (PRIM(_mbw).shadow_thickness),
1220 PRIM(_mbw).shadow_thickness, _direction);
1221 }
1222
timedScroll(XtPointer _closure,XtIntervalId * _id)1223 static void timedScroll(XtPointer _closure, XtIntervalId *_id)
1224 {
1225 XmMegaButtonWidget mbw = (XmMegaButtonWidget)_closure;
1226
1227 scroll((Widget)mbw, TDIR(mbw), TRUE, RDELAY(mbw));
1228 }
1229
scroll(Widget _mbw,int _direction,Boolean _addTimeout,int _delay)1230 static void scroll(Widget _mbw, int _direction, Boolean _addTimeout, int _delay)
1231 {
1232 Position sy, dy;
1233
1234 TIMER(_mbw) = -1;
1235
1236 if (_direction == XmTRAVERSE_DOWN)
1237 {
1238 if ((FPOS(_mbw) + VIS_COUNT(_mbw)) >= ICOUNT(_mbw))
1239 return;
1240
1241 /* drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE); */
1242
1243 sy = 2 * EL_HEIGHT(_mbw) + MINI_SEP_HEIGHT;
1244 dy = sy - EL_HEIGHT(_mbw);
1245
1246 XCopyArea(XtDisplay(_mbw), XtWindow(_mbw), XtWindow(_mbw),
1247 COPY_GC(_mbw),
1248 0, sy, WIDTH(_mbw), EL_HEIGHT(_mbw) * (VIS_COUNT(_mbw)-1),
1249 0, dy);
1250
1251 XClearArea(XtDisplay(_mbw), XtWindow(_mbw),
1252 PRIM(_mbw).shadow_thickness, dy + EL_HEIGHT(_mbw) * (VIS_COUNT(_mbw)-1),
1253 WIDTH(_mbw)-2*PRIM(_mbw).shadow_thickness,
1254 EL_HEIGHT(_mbw), FALSE);
1255
1256 FPOS(_mbw)++;
1257
1258 LABEL(_mbw)._label = ITEMS(_mbw)[FPOS(_mbw)+VIS_COUNT(_mbw)-1];
1259 _XmCalcLabelDimensions((Widget)_mbw);
1260
1261 LABEL(_mbw).TextRect.y = YOFFSET(_mbw) + (VIS_COUNT(_mbw)*EL_HEIGHT(_mbw)) + MINI_SEP_HEIGHT;
1262 LABEL(_mbw).TextRect.x = XOFFSET(_mbw);
1263
1264
1265 (*xmLabelWidgetClass->core_class.expose)
1266 ((Widget)_mbw, NULL, (Region)NULL);
1267
1268
1269 if ( (MODE(_mbw) == XmMODE_TOGGLE_BUTTON) &&
1270 ((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)
1271
1272 {
1273 if ((FPOS(_mbw)+VIS_COUNT(_mbw)-1) == SET_POS(_mbw))
1274 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)(_mbw, LABEL(_mbw).TextRect.x, LABEL(_mbw).TextRect.y, TRUE);
1275 else
1276 if (VIS_W_OFF(_mbw))
1277 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)
1278 (_mbw, LABEL(_mbw).TextRect.x, LABEL(_mbw).TextRect.y, FALSE);
1279 }
1280
1281 if (_addTimeout && ((FPOS(_mbw) + VIS_COUNT(_mbw)) < ICOUNT(_mbw)))
1282 {
1283 TDIR(_mbw) = XmTRAVERSE_DOWN;
1284 TIMER(_mbw) = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)_mbw),
1285 (unsigned long) _delay,
1286 timedScroll, (XtPointer)_mbw);
1287 }
1288
1289 }
1290 else
1291 if (_direction == XmTRAVERSE_UP)
1292 {
1293 if (FPOS(_mbw) == 0)
1294 return;
1295
1296 /* drawShadowedItem(_mbw, VIS_POS(_mbw), TRUE); */
1297
1298 sy = EL_HEIGHT(_mbw) + MINI_SEP_HEIGHT;
1299 dy = sy + EL_HEIGHT(_mbw);
1300
1301 XCopyArea(XtDisplay(_mbw), XtWindow(_mbw), XtWindow(_mbw),
1302 COPY_GC(_mbw),
1303 0, sy, WIDTH(_mbw), EL_HEIGHT(_mbw) * (VIS_COUNT(_mbw)-1),
1304 0, dy);
1305
1306 XClearArea(XtDisplay(_mbw), XtWindow(_mbw),
1307 PRIM(_mbw).shadow_thickness, EL_HEIGHT(_mbw) + MINI_SEP_HEIGHT,
1308 WIDTH(_mbw)-2*PRIM(_mbw).shadow_thickness,
1309 EL_HEIGHT(_mbw), FALSE);
1310
1311 FPOS(_mbw)--;
1312
1313 LABEL(_mbw)._label = ITEMS(_mbw)[FPOS(_mbw)];
1314 _XmCalcLabelDimensions((Widget)_mbw);
1315
1316 LABEL(_mbw).TextRect.y = YOFFSET(_mbw) + EL_HEIGHT(_mbw) + MINI_SEP_HEIGHT;
1317 LABEL(_mbw).TextRect.x = XOFFSET(_mbw);
1318
1319
1320 (*xmLabelWidgetClass->core_class.expose) ((Widget)_mbw, NULL, (Region)NULL);
1321
1322 if ( (MODE(_mbw) == XmMODE_TOGGLE_BUTTON) &&
1323 ((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)
1324
1325 {
1326 if (FPOS(_mbw) == SET_POS(_mbw))
1327 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)
1328 (_mbw, LABEL(_mbw).TextRect.x, LABEL(_mbw).TextRect.y, TRUE);
1329 else
1330 if (VIS_W_OFF(_mbw))
1331 (*((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleDrawProc)
1332 (_mbw, LABEL(_mbw).TextRect.x, LABEL(_mbw).TextRect.y, FALSE);
1333 }
1334
1335
1336 if (_addTimeout && (FPOS(_mbw) != 0))
1337 {
1338 TDIR(_mbw) = XmTRAVERSE_UP;
1339 TIMER(_mbw) = XtAppAddTimeOut(XtWidgetToApplicationContext((Widget)_mbw),
1340 (unsigned long) _delay,
1341 timedScroll, (XtPointer)_mbw);
1342 }
1343 }
1344
1345 if (_direction == XmTRAVERSE_DOWN)
1346 {
1347 if (FPOS(_mbw) != 0)
1348 {
1349 if (((ICOUNT(_mbw))-FPOS(_mbw)) <= VIS_COUNT(_mbw))
1350 {
1351 clearArrow(_mbw, VIS_COUNT(_mbw)+1);
1352 drawArrow(_mbw, VIS_COUNT(_mbw)+1, XmARROW_DOWN, FALSE);
1353 }
1354 drawArrow(_mbw, 0, XmARROW_UP, TRUE);
1355 }
1356
1357 }
1358 else
1359 {
1360 if (FPOS(_mbw) == 0)
1361 {
1362 clearArrow(_mbw, 0);
1363 drawArrow(_mbw, 0, XmARROW_UP, FALSE);
1364 }
1365 drawArrow(_mbw, VIS_COUNT(_mbw)+1, XmARROW_DOWN, TRUE);
1366 }
1367 }
1368
toggleDrawProc(Widget _mbw,Position _x,Position _y,Boolean _on)1369 static void toggleDrawProc(Widget _mbw, Position _x, Position _y, Boolean _on)
1370 {
1371 int ecalc;
1372
1373 ecalc = STR_HEIGHT(_mbw) - 2 * PRIM(_mbw).shadow_thickness;
1374
1375 if (ecalc < 5)
1376 ecalc = 5;
1377
1378 _y += EL_HEIGHT(_mbw)/2 - ecalc/2 - PRIM(_mbw).shadow_thickness;
1379
1380 _x -= (ecalc + LABEL(_mbw).margin_width);
1381
1382 _XmDrawDiamond(XtDisplay((Widget)_mbw), XtWindow((Widget)_mbw),
1383 _on ? PRIM(_mbw).bottom_shadow_GC : PRIM(_mbw).top_shadow_GC,
1384 _on ? PRIM(_mbw).top_shadow_GC : PRIM(_mbw).bottom_shadow_GC,
1385 _on ? SELECT_GC(_mbw) : COPY_GC(_mbw),
1386 _x, _y,
1387 ecalc, ecalc,
1388 PRIM(_mbw).shadow_thickness,
1389 TRUE);
1390 }
1391
toggleSpaceProc(Widget _mbw,Dimension * _width,Dimension * _height)1392 static void toggleSpaceProc(Widget _mbw, Dimension *_width, Dimension *_height)
1393 {
1394 int ecalc = STR_HEIGHT(_mbw) - 2 * PRIM(_mbw).shadow_thickness;
1395 if (ecalc < 5)
1396 ecalc = 5;
1397
1398 XOFFSET(_mbw) += ecalc + LABEL(_mbw).margin_width;
1399 *_width += ecalc + LABEL(_mbw).margin_width;
1400 }
1401
findGoodShowPos(Widget _mbw)1402 static void findGoodShowPos(Widget _mbw)
1403 {
1404 int topDiff, bottomDiff;
1405
1406 if (MODE(_mbw) != XmMODE_TOGGLE_BUTTON)
1407 {
1408 FPOS(_mbw) = 0;
1409 return;
1410 }
1411
1412 VIS_POS(_mbw) = 0;
1413 if (!HAS_ARROWS(_mbw) || (SET_POS(_mbw) == -1))
1414 FPOS(_mbw) = 0;
1415 else
1416 {
1417 topDiff = SET_POS(_mbw) - VIS_COUNT(_mbw)/2;
1418 if (topDiff < 0)
1419 FPOS(_mbw) = 0;
1420 else
1421 {
1422 bottomDiff = (ICOUNT(_mbw)-1) - SET_POS(_mbw);
1423
1424 if (bottomDiff < VIS_COUNT(_mbw))
1425 FPOS(_mbw) = (ICOUNT(_mbw))-VIS_COUNT(_mbw);
1426 else
1427 FPOS(_mbw) = topDiff;
1428 }
1429 }
1430 }
1431
toLower(char * _str1,char * _str2,int _length)1432 static void toLower(char *_str1, char *_str2, int _length)
1433 {
1434 int i;
1435 char *ptr;
1436
1437 for(ptr=_str1,i=0;(ptr!=NULL) && (i<_length);ptr++,i++)
1438 *(_str2+i) = tolower(*ptr);
1439 }
1440
cvtStringToMegaButtonMode(Display * _display,XrmValuePtr _args,Cardinal * _numArgs,XrmValuePtr _from,XrmValuePtr _to,XtPointer * _data)1441 static Boolean cvtStringToMegaButtonMode(Display *_display, XrmValuePtr _args,
1442 Cardinal *_numArgs, XrmValuePtr _from, XrmValuePtr _to, XtPointer *_data)
1443 {
1444 char *lower;
1445 static unsigned char mode;
1446 Boolean badConversion = FALSE;
1447
1448 if (*_numArgs != 0)
1449 {
1450 XtAppWarningMsg(XtDisplayToApplicationContext(_display), "cvtStringToMegaButtonMode", "wrongParamaters",
1451 "ResourceError",
1452 "cvtStringToMegaButtonMode needs no arguments.",
1453 (String *)NULL, (Cardinal *)NULL);
1454 }
1455
1456 lower = XtNewString(_from->addr);
1457 toLower(_from->addr, lower, strlen(_from->addr));
1458
1459 mode = XmMODE_TOGGLE_BUTTON;
1460
1461 if (!strncmp(lower, "mode_toggle_button", 18))
1462 mode = XmMODE_TOGGLE_BUTTON;
1463 else
1464 if (!strncmp(lower, "mode_push_button", 16))
1465 mode = XmMODE_PUSH_BUTTON;
1466 else
1467 if (!strncmp(lower, "toggle_button", 13))
1468 mode = XmMODE_TOGGLE_BUTTON;
1469 else
1470 if (!strncmp(lower, "push_button", 11))
1471 mode = XmMODE_PUSH_BUTTON;
1472 else
1473 badConversion = TRUE;
1474
1475 XtFree(lower);
1476
1477 if (badConversion)
1478 XtDisplayStringConversionWarning(_display, _from->addr, XmRMegaButtonMode);
1479 else
1480 {
1481 if (_to->addr == NULL)
1482 _to->addr = (XtPointer)&mode;
1483 else
1484 if (_to->size < sizeof(unsigned char))
1485 badConversion = TRUE;
1486 else
1487 *(unsigned char *)_to->addr = mode;
1488 _to->size = sizeof(unsigned char);
1489 }
1490
1491 return !badConversion;
1492 }
1493
1494
XmMegaButtonAddItem(Widget _w,XmString _item,int _pos,XtPointer _cbData)1495 void XmMegaButtonAddItem(Widget _w, XmString _item, int _pos, XtPointer _cbData)
1496 {
1497 XmMegaButtonWidget mbw;
1498
1499 if (!XmIsMegaButton(_w))
1500 return;
1501
1502 mbw = (XmMegaButtonWidget)_w;
1503
1504 if (FAKE_ITEM(mbw))
1505 {
1506 ICOUNT(mbw)--;
1507 FAKE_ITEM(mbw) = FALSE;
1508 WIDTH(mbw) = 0;
1509 MAX_STRING_WIDTH(mbw) = 1;
1510 }
1511
1512 if ((_pos < 0) || (_pos > (ICOUNT(mbw))))
1513 _pos = ICOUNT(mbw);
1514
1515 if (ICOUNT(mbw) == CUR_SIZE(mbw))
1516 {
1517 CUR_SIZE(mbw) += CHUNK_SIZE(mbw);
1518 ITEMS(mbw) = (_XmString *)XtRealloc((char *)ITEMS(mbw), sizeof(_XmString) * CUR_SIZE(mbw));
1519 DATA(mbw) = (XtPointer *)XtRealloc((char *)DATA(mbw), sizeof(XtPointer) * CUR_SIZE(mbw));
1520 }
1521
1522 bcopy(ITEMS(mbw)+_pos, ITEMS(mbw)+_pos+1, (ICOUNT(mbw)-_pos) * sizeof(_XmString));
1523 bcopy(DATA(mbw)+_pos, DATA(mbw)+_pos+1, (ICOUNT(mbw)-_pos) * sizeof(XtPointer));
1524
1525 ITEMS(mbw)[_pos] = _XmStringCreate(_item);
1526 DATA(mbw)[_pos] = _cbData;
1527 ICOUNT(mbw)++;
1528
1529 recheckSizesAtPos((Widget)mbw, _pos);
1530 }
1531
recheckSizesAtPos(Widget _mbw,int _pos)1532 static void recheckSizesAtPos(Widget _mbw, int _pos)
1533 {
1534 ShellWidget popupShell;
1535 XtGeometryResult result;
1536
1537 popupShell = (ShellWidget)XtGetShell((Widget)_mbw);
1538 if (popupShell && !popupShell->shell.popped_up)
1539 {
1540 Dimension width, height;
1541 Dimension replyWidth, replyHeight, oldWidth;
1542
1543 width = WIDTH(_mbw);
1544 height = HEIGHT(_mbw);
1545
1546 if (!HAS_ARROWS(_mbw))
1547 {
1548 HAS_ARROWS(_mbw) = ICOUNT(_mbw) > VIS_COUNT(_mbw);
1549
1550 if (!HAS_ARROWS(_mbw))
1551 height = EL_HEIGHT(_mbw) * ICOUNT(_mbw);
1552 else
1553 height = EL_HEIGHT(_mbw) * (VIS_COUNT(_mbw) + 2) + 2 * MINI_SEP_HEIGHT;
1554 }
1555
1556 LABEL(_mbw)._label = ITEMS(_mbw)[_pos];
1557 _XmCalcLabelDimensions((Widget)_mbw);
1558
1559 if (LABEL(_mbw).TextRect.width > MAX_STRING_WIDTH(_mbw))
1560 {
1561 MAX_STRING_WIDTH(_mbw) = LABEL(_mbw).TextRect.width;
1562 MAX_STRING_POS(_mbw) = _pos;
1563 oldWidth = WIDTH(_mbw);
1564 WIDTH(_mbw) = 0;
1565 (*xmLabelWidgetClass->core_class.resize) ((Widget)_mbw);
1566 width = WIDTH(_mbw);
1567 WIDTH(_mbw) = oldWidth;
1568
1569 /* YOFFSET(_mbw) = LABEL(_mbw).TextRect.y; */
1570 XOFFSET(_mbw) = LABEL(_mbw).TextRect.x;
1571
1572 if ( (MODE(_mbw) == XmMODE_TOGGLE_BUTTON) &&
1573 ( ((XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleSpaceProc))
1574 (( (XmMegaButtonWidgetClass)XtClass(_mbw))->mega_button_class.toggleSpaceProc)
1575 (_mbw, &width, &EL_HEIGHT(_mbw));
1576 }
1577
1578 if (height == 0)
1579 height = 2 * PRIM(_mbw).shadow_thickness;
1580 if (width == 0)
1581 width = 2 * PRIM(_mbw).shadow_thickness;
1582
1583 while((result = XtMakeResizeRequest((Widget)_mbw, width, height, &replyWidth,
1584 &replyHeight)) == XtGeometryAlmost)
1585 {
1586 width = replyWidth;
1587 height = replyHeight;
1588 }
1589 }
1590 }
1591
XmMegaButtonRemoveItem(Widget _w,int _pos)1592 XtPointer XmMegaButtonRemoveItem(Widget _w, int _pos)
1593 {
1594 XtPointer data;
1595 XmMegaButtonWidget mbw;
1596
1597 mbw = (XmMegaButtonWidget)_w;
1598
1599 if ((_pos < 0) || (_pos >= ICOUNT(mbw)))
1600 return NULL;
1601
1602 _XmStringFree(ITEMS(mbw)[_pos]);
1603 data = DATA(mbw)[_pos];
1604
1605 ICOUNT(mbw)--;
1606 bcopy(ITEMS(mbw)+_pos+1, ITEMS(mbw)+_pos, (ICOUNT(mbw)-_pos) * sizeof(_XmString));
1607 bcopy(DATA(mbw)+_pos+1, DATA(mbw)+_pos, (ICOUNT(mbw)-_pos) * sizeof(XtPointer));
1608
1609 if (ICOUNT(mbw) != 0)
1610 recheckSizesAtPos((Widget)mbw, 0);
1611
1612 return data;
1613 }
1614
XmMegaButtonItemCount(Widget _w,Boolean _forgetFake)1615 int XmMegaButtonItemCount(Widget _w, Boolean _forgetFake)
1616 {
1617 XmMegaButtonWidget mbw;
1618
1619 mbw = (XmMegaButtonWidget)_w;
1620
1621 if (_forgetFake && FAKE_ITEM(mbw))
1622 return 0;
1623 else
1624 return (ICOUNT(mbw));
1625 }
1626
1627
XmMegaButtonGetPos(Widget _w)1628 int XmMegaButtonGetPos(Widget _w)
1629 {
1630 XmMegaButtonWidget mbw;
1631
1632 mbw = (XmMegaButtonWidget)_w;
1633 if (MODE(mbw) == XmMODE_TOGGLE_BUTTON)
1634 return SET_POS(mbw);
1635 else
1636 return -1;
1637 }
1638
XmMegaButtonSetPos(Widget _w,int _pos)1639 void XmMegaButtonSetPos(Widget _w, int _pos)
1640 {
1641 XmMegaButtonWidget mbw;
1642
1643 mbw = (XmMegaButtonWidget)_w;
1644 if (MODE(mbw) == XmMODE_TOGGLE_BUTTON)
1645 {
1646 if (_pos > (ICOUNT(mbw)-1))
1647 _pos = ICOUNT(mbw) - 1;
1648
1649 SET_POS(mbw) = _pos;
1650 }
1651 }
1652
XmMegaButtonGetXmStringAtPos(Widget _w,int _pos)1653 extern XmString XmMegaButtonGetXmStringAtPos(Widget _w, int _pos)
1654 {
1655 XmMegaButtonWidget mbw = (XmMegaButtonWidget)_w;
1656
1657 if ((_pos >= 0) && (_pos < ICOUNT(mbw)))
1658 return _XmStringCreateExternal(LABEL(mbw).font, ITEMS(mbw)[_pos]);
1659
1660 return (XmString)NULL;
1661 }
1662
XmMegaButtonSetXmStringAtPos(Widget _w,XmString _xmstring,int _pos)1663 extern void XmMegaButtonSetXmStringAtPos(Widget _w, XmString _xmstring, int _pos)
1664 {
1665 XmMegaButtonWidget mbw = (XmMegaButtonWidget)_w;
1666
1667 if ((_pos >= 0) && (_pos < ICOUNT(mbw)))
1668 {
1669 _XmStringFree(ITEMS(mbw)[_pos]);
1670 ITEMS(mbw)[_pos] = _XmStringCreate(_xmstring);
1671 recheckSizesAtPos((Widget)mbw, _pos);
1672 }
1673 }
1674