1 /***********************************************************************/
2 /* Open Visualization Data Explorer */
3 /* (C) Copyright IBM Corp. 1989,1999 */
4 /* ALL RIGHTS RESERVED */
5 /* This code licensed under the */
6 /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */
7 /***********************************************************************/
8
9 #include <dxconfig.h>
10 #include <defines.h>
11
12
13
14
15 #include <Xm/Xm.h>
16 #include <Xm/RowColumn.h>
17 #include <Xm/CascadeB.h>
18
19 #include "CascadeMenu.h"
20 #include "DXStrings.h"
21 #include "ListIterator.h"
22
23
CascadeMenu(char * name,Widget parent)24 CascadeMenu::CascadeMenu(char* name, Widget parent) : UIComponent(name)
25 {
26 #define BUFLEN 100
27 #define NAME "Submenu"
28 #define NAMELEN 7
29 char *pulldownName, buffer[BUFLEN];
30 int len = STRLEN(name);
31
32
33 if (len > BUFLEN-NAMELEN-1)
34 pulldownName = new char[ len + NAMELEN];
35 else
36 pulldownName = buffer;
37
38 sprintf(pulldownName,"%s%s",name,NAME);
39
40 this->subMenu = XmCreatePulldownMenu(parent, pulldownName,
41 NUL(ArgList), 0);
42
43 Widget cascade = XtVaCreateManagedWidget
44 (name,
45 xmCascadeButtonWidgetClass,
46 parent,
47 XmNsubMenuId, subMenu,
48 NULL);
49
50 this->setRootWidget(cascade);
51
52 if (pulldownName != buffer)
53 delete pulldownName;
54 }
55
56
~CascadeMenu()57 CascadeMenu::~CascadeMenu()
58 {
59 this->clearComponents();
60 // FIXME: when/if to destroy this.
61 // Does the parent own it or this class.
62 // XtDestroyWidget(this->subMenu);
63 }
64
65 #if 0
66 //
67 // Build the cascaded menu.
68 // This must be done before creating the components that will reside in the
69 // menu so that getMenuItemParent() can succeed.
70 //
71 void CascadeMenu::createMenu()
72 {
73 this->clearComponents();
74
75 this->subMenu = XmCreatePulldownMenu(parent, "subMenu", NUL(ArgList), 0);
76
77 Widget cascade = XtVaCreateManagedWidget
78 (name,
79 xmCascadeButtonWidgetClass,
80 parent,
81 XmNsubMenuId, subMenu,
82 NULL);
83
84 this->setRootWidget(cascade);
85 }
86 #endif
87
88 //
89 // Get the parent of the UIComponents that are to be added to the cascaded
90 // menu.
91 //
getMenuItemParent()92 Widget CascadeMenu::getMenuItemParent()
93 {
94 ASSERT(this->subMenu);
95 return this->subMenu;
96 }
97
98 //
99 // Append the given UIComponent to the sub menu and manage it.
100 //
appendComponent(UIComponent * uic)101 boolean CascadeMenu::appendComponent(UIComponent *uic)
102 {
103 ASSERT(this->subMenu == XtParent(uic->getRootWidget()));
104
105 if (!this->componentList.appendElement(uic))
106 return FALSE;
107
108 uic->manage();
109 return TRUE;
110 }
111 //
112 // Remove (but do not delete) the given UIComponent from the submenu and
113 // unmanage it.
114 //
removeComponent(UIComponent * uic)115 boolean CascadeMenu::removeComponent(UIComponent *uic)
116 {
117 if (!this->componentList.removeElement(uic))
118 return FALSE;
119
120 uic->unmanage();
121 return TRUE;
122 }
123 //
124 // Remove and delete the given UIComponent from the submenu.
125 //
deleteComponent(UIComponent * uic)126 boolean CascadeMenu::deleteComponent(UIComponent *uic)
127 {
128 if (!this->componentList.removeElement(uic))
129 return FALSE;
130
131 delete uic;
132 return TRUE;
133 }
134 //
135 // Remove and delete all UIComponents owned by the menu.
136 //
clearComponents()137 void CascadeMenu::clearComponents()
138 {
139 UIComponent *uic;
140
141 while ((uic = (UIComponent*)this->componentList.getElement(1))) {
142 this->componentList.deleteElement(1);
143 delete uic;
144 }
145
146 }
147 //
148 // Set the label of the Cascade menu
149 //
setLabel(const char * label)150 void CascadeMenu::setLabel(const char *label)
151 {
152 Arg arg[1];
153 XmString name;
154
155 name = XmStringCreateSimple((char*)label);
156 XtSetArg(arg[0],XmNlabelString, name);
157 XtSetValues(this->getRootWidget(), arg, 1);
158
159 XmStringFree(name);
160
161 }
162
163
164 //
165 // Set the sensitivity of the cascade menu item based on the sensitivity
166 // of its immediate children. If any are sensitive, then set the sensitivity
167 // to true (active) else not sensitive. We return TRUE if the cascade was
168 // set active, otherwise FALSE.
169 //
setActivationFromChildren()170 boolean CascadeMenu::setActivationFromChildren()
171 {
172 UIComponent *uic;
173 ListIterator iterator(this->componentList);
174 boolean active = FALSE;
175
176 while(!active && (uic = (UIComponent*)iterator.getNext())) {
177 if (uic->isActivated())
178 active = TRUE;
179 }
180
181 if (active)
182 this->activate();
183 else
184 this->deactivate();
185
186 return active;
187 }
188