1 /* $TOG: MenuBar.C /main/6 1997/06/03 16:12:28 mgreess $ */
5 * RESTRICTED CONFIDENTIAL INFORMATION:
7 * The information in this document is subject to special
8 * restrictions in a confidential disclosure agreement bertween
9 * HP, IBM, Sun, USL, SCO and Univel. Do not distribute this
10 * document outside HP, IBM, Sun, USL, SCO, or Univel wihtout
11 * Sun's specific written approval. This documment and all copies
12 * and derivative works thereof must be returned or destroyed at
15 * Copyright 1993, 1994, 1995 Sun Microsystems, Inc. All rights reserved.
19 ///////////////////////////////////////////////////////////////////////////////
20 //////////////////////////////////////////////////////////////////////////////
21 // This example code is from the book:
23 // Object-Oriented Programming with C++ and OSF/Motif
26 // Prentice Hall, 1992
29 // Copyright 1991 by Prentice Hall
30 // All Rights Reserved
32 // Permission to use, copy, modify, and distribute this software for
33 // any purpose except publication and without fee is hereby granted, provided
34 // that the above copyright notice appear in all copies of the software.
35 ///////////////////////////////////////////////////////////////////////////////
36 //////////////////////////////////////////////////////////////////////////////
39 //////////////////////////////////////////////////////////
40 // MenuBar.C: A menu bar whose panes support items
42 //////////////////////////////////////////////////////////
44 ////////////////////////////////////////////////////////////
45 // MODIFIED TO SUPPORT SUBMENUS - not described in Book
46 ///////////////////////////////////////////////////////////
49 #include "Application.h"
53 #include "ToggleButtonInterface.h"
54 #include "ButtonInterface.h"
56 #include <Xm/RowColumn.h>
57 #include <Xm/CascadeB.h>
58 #include <Xm/Separator.h>
64 extern XtPointer _XmStringUngenerate (
68 XmTextType output_type);
71 MenuBar::MenuBar ( Widget parent, char *name, unsigned char type )
72 : UIComponent ( name )
74 // Base widget is a Motif menu bar widget
79 if( type == XmMENU_POPUP) {
83 XtSetArg(args[i], XmNwhichButton, theApplication->bMenuButton()); i++;
84 _w = XmCreatePopupMenu( parent, _name, args, i );
85 // XtVaSetValues(_w, XmNwhichButton, theApplication->bMenuButton(), NULL);
87 type = XmMENU_BAR; // Force it to menu bar
88 _w = XmCreateMenuBar ( parent, _name, NULL, 0 );
91 printHelpId("_w", _w);
92 /* install callback */
93 // XtAddCallback(_w, XmNhelpCallback, HelpCB, helpId);
95 installDestroyHandler();
97 Widget MenuBar::addCommands ( Widget *menuBarCascade, CmdList *list, Boolean help, unsigned char type )
99 return( createPulldown ( _w, list, menuBarCascade, help, type ) );
102 Widget MenuBar::addCommands ( CmdList *list, Boolean help, unsigned char type )
104 return( createPulldown ( _w, list, help, type ) );
108 MenuBar::createPulldown (
121 if(type != XmMENU_POPUP)
124 // Create a pulldown menu pane for this list of commands
126 if( type == XmMENU_BAR) {
127 pulldown = XmCreatePulldownMenu( parent,
128 (char *) list->name(), NULL, 0 );
129 label_str = XmStringCreateLocalized(list->getLabel());
130 XtVaSetValues(pulldown,
131 XmNlabelString, label_str,
133 printHelpId("pulldown", pulldown);
134 /* install callback */
135 // XtAddCallback(pulldown, XmNhelpCallback, HelpCB, helpId);
138 // Each entry in the menu bar must have a cascade button
139 // from which the user can pull down the pane
141 if (cascade != NULL && *cascade != NULL)
142 XtVaSetValues (*cascade, XmNsubMenuId, pulldown,
143 XmNlabelString, label_str,
147 XtSetArg(args2[0], XmNsubMenuId, pulldown);
148 *cascade = XtCreateWidget ( list->name(),
149 xmCascadeButtonWidgetClass,
152 XtVaSetValues(*cascade,
153 XmNlabelString, label_str,
156 XtSetArg (args2[0], XmNmenuHelpWidget, *cascade);
157 XtSetValues (parent, args2, 1);
160 XtManageChild ( *cascade );
161 printHelpId("cascade", *cascade);
162 /* install callback */
165 // Install callbacks for each of the
166 // pulldown menus so we can get
167 // On Item help for them.
169 helpId = XtName(*cascade);
170 if (helpId == "Mailbox") {
171 XtAddCallback(*cascade, XmNhelpCallback,
172 HelpCB, DTMAILCONTAINERMENUID);
173 } else if (helpId == "Edit") {
174 XtAddCallback(*cascade, XmNhelpCallback,
175 HelpCB, DTMAILEDITMENUID);
176 } else if (helpId == "Message") {
177 XtAddCallback(*cascade, XmNhelpCallback,
178 HelpCB, DTMAILMESSAGEMENUID);
179 } else if (helpId == "Attachments") {
180 XtAddCallback(*cascade, XmNhelpCallback,
181 HelpCB, DTMAILATTACHMENUID);
182 } else if (helpId == "View") {
183 XtAddCallback(*cascade, XmNhelpCallback,
184 HelpCB, DTMAILVIEWMENUID);
185 } else if (helpId == "Compose") {
186 XtAddCallback(*cascade, XmNhelpCallback,
187 HelpCB, DTMAILCOMPOSEMENUID);
195 // Loop through the cmdList, creating a menu
196 // entry for each command.
197 Widget *head_wl, *wl;
199 head_wl = wl = new Widget[ list->size() ];
201 for ( i = 0; i < list->size(); i++)
204 if(!strcmp((*list)[i]->className(), "CmdList")) {
205 Widget pane = createPulldown(pulldown,
206 (CmdList*) (*list)[i], FALSE, XmMENU_BAR);
207 ((CmdList *)(*list)[i])->setPaneWidget(pane);
208 label_str = XmStringCreateLocalized(((CmdList *)(*list)[i])->getLabel());
210 XmNlabelString, label_str,
213 if ( !strcmp((*list)[i]->className(),"SeparatorCmd")) {
214 *(wl++) = XtCreateWidget ( (*list)[i]->name(),
215 xmSeparatorWidgetClass,
218 } else if (!strcmp((*list)[i]->className(),"ToggleButtonCmd")) {
220 ci = new ToggleButtonInterface(pulldown, (*list)[i] );
221 *(wl++) = ci->baseWidget();
222 } else if(!strcmp((*list)[i]->className(),"LabelCmd")) {
223 label_str = XmStringCreateLocalized((*list)[i]->getLabel());
225 *(wl++) = XtVaCreateWidget ( (*list)[i]->name(),
228 XmNlabelString, label_str,
232 ci = new ButtonInterface ( pulldown, (*list)[i] );
233 *(wl++) = ci->baseWidget();
240 XtManageChildren ( head_wl, num_wl );
247 MenuBar::createPulldown (
254 Widget pulldown, cascade;
259 if(type != XmMENU_POPUP)
262 // Create a pulldown menu pane for this list of commands
264 if( type == XmMENU_BAR) {
265 pulldown = XmCreatePulldownMenu( parent,
266 (char *) list->name(), NULL, 0 );
267 label_str = XmStringCreateLocalized(list->getLabel());
268 XtVaSetValues(pulldown,
269 XmNlabelString, label_str,
271 printHelpId("pulldown", pulldown);
272 /* install callback */
273 // XtAddCallback(pulldown, XmNhelpCallback, HelpCB, helpId);
276 // Each entry in the menu bar must have a cascade button
277 // from which the user can pull down the pane
279 XtSetArg(args2[0], XmNsubMenuId, pulldown);
280 cascade = XtCreateWidget ( list->name(),
281 xmCascadeButtonWidgetClass,
284 XtVaSetValues(cascade,
285 XmNlabelString, label_str,
288 XtSetArg (args2[0], XmNmenuHelpWidget, cascade);
289 XtSetValues (parent, args2, 1);
292 XtManageChild ( cascade );
293 printHelpId("cascade", cascade);
294 /* install callback */
297 // Install callbacks for each of the
298 // pulldown menus so we can get
299 // On Item help for them.
301 helpId = XtName(cascade);
302 if (helpId == "Mailbox") {
303 XtAddCallback(cascade, XmNhelpCallback,
304 HelpCB, DTMAILCONTAINERMENUID);
305 } else if (helpId == "Edit") {
306 XtAddCallback(cascade, XmNhelpCallback,
307 HelpCB, DTMAILEDITMENUID);
308 } else if (helpId == "Message") {
309 XtAddCallback(cascade, XmNhelpCallback,
310 HelpCB, DTMAILMESSAGEMENUID);
311 } else if (helpId == "Attachments") {
312 XtAddCallback(cascade, XmNhelpCallback,
313 HelpCB, DTMAILATTACHMENUID);
314 } else if (helpId == "View") {
315 XtAddCallback(cascade, XmNhelpCallback,
316 HelpCB, DTMAILVIEWMENUID);
317 } else if (helpId == "Compose") {
318 XtAddCallback(cascade, XmNhelpCallback,
319 HelpCB, DTMAILCOMPOSEMENUID);
326 // Loop through the cmdList, creating a menu
327 // entry for each command.
329 for ( i = 0; i < list->size(); i++)
332 if(!strcmp((*list)[i]->className(), "CmdList")) {
333 Widget pane = createPulldown(pulldown,
334 (CmdList*) (*list)[i], FALSE, XmMENU_BAR);
335 ((CmdList *)(*list)[i])->setPaneWidget(pane);
336 label_str = XmStringCreateLocalized((*list)[i]->getLabel());
338 XmNlabelString, label_str,
341 if ( !strcmp((*list)[i]->className(),"SeparatorCmd")) {
342 XtCreateManagedWidget ( (*list)[i]->name(),
343 xmSeparatorWidgetClass,
346 } else if (!strcmp((*list)[i]->className(),"ToggleButtonCmd")) {
348 ci = new ToggleButtonInterface(pulldown, (*list)[i]);
350 } else if(!strcmp((*list)[i]->className(),"LabelCmd")) {
355 _i18n = XtCreateManagedWidget(
362 xms = XmStringCreateLocalized((char*) (*list)[i]->getLabel());
363 XtSetArg( _args[0], XmNlabelString, xms );
364 XtSetValues( _i18n, _args, 1 );
368 ci = new ButtonInterface ( pulldown, (*list)[i] );
376 // SR - Added to handle dynamic menus
379 MenuBar::addCommands(
384 // if(isValidMenuPane(pulldown) == FALSE)
389 Boolean haveNoSeparator;
390 int newItemIndex, numPBUnmanaged, tmpPBUnmanaged;
392 XtVaGetValues(pulldown,
393 XmNnumChildren, &num_children,
396 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
398 XtVaGetValues(pulldown,
399 XmNchildren, &children,
402 // Handle the creation or management of the Separator.
404 haveNoSeparator = TRUE;
407 for (i=0; (i < num_children); i++) {
408 Widget wid = (Widget) children[i];
409 if (XtIsSubclass(wid, xmSeparatorWidgetClass)) {
411 haveNoSeparator = FALSE;
413 else if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
414 if (!XtIsManaged(wid)) { // If widget is unmanaged
419 if (haveNoSeparator) {
420 XtCreateManagedWidget ("Separator",
421 xmSeparatorWidgetClass,
424 haveNoSeparator = FALSE;
427 // Now handle the pushButton case
432 // Loop through the cmdList, creating a menu
433 // entry for each command.
435 for (newItemIndex = 0; newItemIndex < new_list->size(); newItemIndex++) {
437 tmpPBUnmanaged = numPBUnmanaged;
439 if (numPBUnmanaged > 0) { // If there exists unmanaged PBs
441 (i < num_children) &&
442 (tmpPBUnmanaged == numPBUnmanaged);
445 Widget wid = (Widget) children[i];
447 if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
448 if (!XtIsManaged(wid)) {
449 // If widget is unmanaged
450 // Set its label to be the newItemIndex widget's.
452 // Bump up newItemIndex
454 XmNlabelString, XmStringCreateLocalized(
455 (char *) (*new_list)[newItemIndex]->getLabel()),
463 else { // No unmanaged push buttons available
465 ci = new ButtonInterface (
466 pulldown, (*new_list)[newItemIndex]
476 MenuBar::removeOnlyCommands(
478 CmdList *redundant_list
481 // if(isValidMenuPane(pulldown) == FALSE)
484 int i, j, num_children;
487 XtVaGetValues(pulldown,
488 XmNnumChildren, &num_children,
491 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
493 XtVaGetValues(pulldown,
494 XmNchildren, &children,
497 // Loop through widget list. Destroy those widgets that map to those
498 // in the redundant list.
500 for (i=0; i<num_children; i++) {
502 Widget wid = (Widget) children[i];
504 if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
506 for (j=0; j<redundant_list->size(); j++) {
508 ButtonInterface::mapName((*redundant_list)[j]->name(), name);
509 if (strcmp(XtName(wid), name) == 0) {
510 // The redundant item has been found.
511 XtUnmanageChild(wid);
518 MenuBar::removeCommands(
520 CmdList *redundant_list
523 // if(isValidMenuPane(pulldown) == FALSE)
526 int i, j, num_children;
529 XtVaGetValues(pulldown,
530 XmNnumChildren, &num_children,
533 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
535 XtVaGetValues(pulldown,
536 XmNchildren, &children,
539 // Loop through widget list. Destroy those widgets that map to those
540 // in the redundant list.
542 for (i=0; i<num_children; i++) {
544 Widget wid = (Widget) children[i];
546 if (XtIsSubclass(wid, xmSeparatorWidgetClass)) {
547 XtUnmanageChild(wid);
549 else if (XtIsSubclass(wid, xmPushButtonWidgetClass)) {
551 for (j=0; j<redundant_list->size(); j++) {
554 XtVaGetValues(wid, XmNlabelString, &str, NULL);
555 if (str == NULL) continue;
557 label = (char *) _XmStringUngenerate(
559 XmMULTIBYTE_TEXT, XmMULTIBYTE_TEXT);
561 if (label == NULL) continue;
562 if (strcmp(label, (*redundant_list)[j]->getLabel()) == 0) {
563 // The redundant item has been found.
564 XtUnmanageChild(wid);
578 // if(isValidMenuPane(pulldown) == FALSE)
582 ci = new ButtonInterface ( pulldown, cmd);
587 MenuBar::changeLabel(
593 // if(isValidMenuPane(pulldown) == FALSE)
596 int managed_widgets, i, num_children;
601 XtVaGetValues(pulldown,
602 XmNnumChildren, &num_children,
605 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
607 XtVaGetValues(pulldown,
608 XmNchildren, &children,
611 // Some widgets may be unmanaged, so find the real index
612 for (managed_widgets=0, i=0;
613 managed_widgets <= index && i < num_children; i++) {
614 wid = (Widget) children[i];
615 if (XtIsManaged(wid)) managed_widgets++;
617 if (--i >= num_children) return;
619 wid = (Widget) children[i];
621 label = XmStringCreateLocalized(name);
624 XmNlabelString, label,
630 MenuBar::changeLabel(Widget pulldown,
631 const char * button_name,
634 // if(isValidMenuPane(pulldown) == FALSE)
637 // Locate the appropriate widget in the list.
641 XmString label_string = XmStringCreateLocalized((char *)label);
643 ButtonInterface::mapName(button_name, wid_name);
645 XtVaGetValues(pulldown,
646 XmNnumChildren, &num_children,
649 Widget * children = new Widget[num_children];
650 XtVaGetValues(pulldown,
651 XmNchildren, &children,
654 for (int wid = 0; wid < num_children; wid++) {
655 if (strcmp(XtName(children[wid]), wid_name) == 0) {
656 if (XtIsManaged(children[wid]))
657 XtVaSetValues(children[wid],
658 XmNlabelString, label_string,
663 XmStringFree(label_string);
667 MenuBar::rotateLabels(
673 // if(isValidMenuPane(pulldown) == FALSE)
676 int num_managed_wids=0, i, j, num_children, num_to_change;
678 XmString label, endlabel;
681 if (startindex < 0 || endindex < 0)
684 XtVaGetValues(pulldown,
685 XmNnumChildren, &num_children,
688 if (startindex >= num_children || endindex >= num_children)
691 num_to_change = endindex - startindex;
692 if (num_children < num_to_change || num_to_change == 0)
695 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
697 XtVaGetValues(pulldown,
698 XmNchildren, &children,
701 // Some of the widgets may be unmanaged: find the first managed widget
702 for (i = startindex; i < num_children; i++) {
703 if (XtIsManaged(children[i]))
708 if (startindex == num_children)
711 // Find the real endindex
712 endindex = startindex+1;
713 while (endindex < num_children) {
714 if (XtIsManaged(children[endindex]))
716 if (num_managed_wids == num_to_change)
717 // We have found the endindex at this point
722 if (endindex == num_children)
725 wid = (Widget) children[endindex];
727 XmNlabelString, &label,
729 endlabel = XmStringCopy(label);
732 while (i > startindex) {
735 if (--j < startindex) break;
736 prevwid = (Widget) children[j];
737 } while (!XtIsManaged(prevwid));
739 XtVaGetValues(prevwid,
740 XmNlabelString, &label,
744 XmNlabelString, label,
749 wid = (Widget) children[i];
752 wid = (Widget) children[startindex];
754 XmNlabelString, endlabel,
757 XmStringFree(endlabel);
762 MenuBar::isValidMenuPane(Widget w)
764 Boolean retval = FALSE;
767 while(parent && parent != _w)
768 parent = XtParent(parent);
775 #endif /* DEAD_WOOD */
778 MenuBar::removeCommand(
783 //if(isValidMenuPane(pulldown) == FALSE)
786 int managed_widgets, i, num_children;
789 XtVaGetValues(pulldown,
790 XmNnumChildren, &num_children,
793 children = (WidgetList)XtMalloc(sizeof(Widget) * num_children);
795 XtVaGetValues(pulldown,
796 XmNchildren, &children,
799 // Some widgets may be unmanaged, so find the real index
800 for (managed_widgets=0, i=0;
801 managed_widgets <= index && i < num_children; i++) {
802 Widget wid = (Widget) children[i];
803 if (XtIsManaged(wid)) managed_widgets++;
806 if (--i < num_children)
807 XtUnmanageChild(children[i]);