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 "../base/defines.h"
11 
12 
13 
14 // Interactor.h -
15 //
16 // Definition for the Interactor class.
17 //
18 // The Interactor represents the 'standin' that sits in the ControlPanel
19 // work space.  Each Interactor is tied to an InteractorNode (a stand in
20 // in the Editor workspace) through an InteractorInstance.  The
21 // InteractorInstance stores information local to the Interactor and does
22 // not make any assumptions about the windowing environment.  Each
23 // InteractorNode can have an unlimited number of
24 // Interactor/InteractorInstance pairs.
25 //
26 // There are 3 main sets of methods associated with an Interactor.  The
27 // first has to do with constructing what is displayed in the control
28 // panel work space. All Interactors and derived classes have a basic
29 // layout  and must implement this->createInteractivePart(), which should
30 // build the part that takes input from the user.  This is then placed in
31 // the default layout using this->layoutInteractor().  Before
32 // layoutInteractor() returns this->completeInteractivePart() is called to
33 // finish any thing having to do with the interactor part.  Typically,
34 // this is just calling this->passEvents() so that most events get passed
35 // through interactor part.  The first two of the routines discussed so
36 // far are virtual and so can be redefined for derived classes.
37 //
38 // The second set of methods (just 1 method here) is what to do when
39 // the Interactor in the control panel receives indication that the
40 // default action is to be taken.  this->openDefaultWindow implements
41 // this action.  It is a virtual function and can be redefined, but
42 // at this level is defined to open the set attributes dialog box.
43 //
44 //
45 //
46 
47 //  This is the widget layout of an Interactor.  These widgets are
48 //  created in Interactor.C.  Subclasses create children inside
49 //  this->customPart.  The Workspace widget handles installing translations
50 //  on form (this->root).  Interactor::createInteractor handles translations
51 //  for label and customPart.  passEvents() handles whatever extra widgets are
52 //  created by a subclass.
53 //
54 // --------f-o-r-m-------------------
55 // -                                -
56 // -                                -
57 // -   ----l-a-b-e-l------------    -
58 // -   -                       -    -
59 // -   -                       -    -
60 // -   -------------------------    -
61 // -                                -
62 // -   ---c-u-s-t-o-m-P-a-r-t---    -
63 // -   -                       -    -
64 // -   -                       -    -
65 // -   -                       -    -
66 // -   -                       -    -
67 // -   -                       -    -
68 // -   -                       -    -
69 // -   -------------------------    -
70 // -                                -
71 // -                                -
72 // ----------------------------------
73 //
74 // Functions for selecting and resizing are no longer here.  They live
75 // in WorkSpaceComponent instead.
76 //
77 
78 #ifndef _Interactor_h
79 #define _Interactor_h
80 
81 #include <X11/Intrinsic.h>
82 #include <Xm/Xm.h>
83 #include "DXDragSource.h"
84 
85 #include "WorkSpaceComponent.h"
86 
87 //
88 // Class name definition:
89 //
90 #define ClassInteractor	"Interactor"
91 
92 typedef long InteractorStatusChange;
93 
94 class InteractorNode;
95 class InteractorInstance;
96 class Node;
97 class Network;
98 class ControlPanel;
99 class Dialog;
100 
101 extern void *GetUserData(Widget widget);
102 
103 extern "C" Boolean Interactor_DragDropWP(XtPointer);
104 
105 //
106 // Virtual Interactor class definition:
107 //
108 class Interactor : public WorkSpaceComponent, public DXDragSource
109 {
110     friend class InteractorStyle;	// It calls this->createInteractor().
111 
112   private:
113     //
114     // Private member data:
115     //
116     // The frame is in this->root
117     Widget		label;
118 
119     static boolean InteractorClassInitialized;
120     static Widget DragIcon;
121 
122     // 1 dictionary for the class... Holds the type which can be dragged from
123     // an interactor.
124     static Dictionary *DragTypeDictionary;
125 
126     // 1 enum for each type of Drag data we can supply.  Pass these to addSupportedType
127     // and decode them in decodeDragType.  These replace the use of func pointers.
128     enum {
129 	Modules,
130 	Trash
131     };
132 
133     //
134     // Shift+Dragging an Interactor has the effect of deleting the
135     // original interactor.  The new Motif doesn't permit deleting
136     // an object involved in a drag-n-drop operation during the
137     // operation.  We used to delete the interactor in the dropFinish()
138     // method.  Now we create a work proc.  This way the deletion
139     // will happen immediately following completion of the drag-n-drop.
140     //
141     int drag_drop_wpid;
142 
143     friend Boolean Interactor_DragDropWP(XtPointer);
144 
145   protected:
146     //
147     // Protected member data:
148     //
149 
150     //
151     // The interactor instance that this interactor is associated with
152     //
153     InteractorInstance		*interactorInstance;
154 
155     static String DefaultResources[];
156 
157     //
158     // To the parent's version add dnd participation.
159     //
160     virtual void passEvents(Widget w, boolean dnd);
161 
162     //
163     // Build the complete interactor.  Make a form and a label and
164     // invoke the subclasses ::createInteractivePart method.
165     //
166     void createInteractor();
167 
168     //
169     // Create the actual interactive Widget(s).  The parent is this->customPart
170     // and is guaranteed to be an XmForm.
171     //
172     virtual Widget createInteractivePart(Widget p)=0;
173 
174     //
175     // Perform any actions that need to be done after the parent of
176     // this->interactivePart has been managed.  This may include a call
177     // to Interactor::passEvents().
178     //
179     virtual void completeInteractivePart() = 0;
180 
181 
182     //
183     //  Layout/size the root, label and interactivePart widgets.
184     //
185     void layoutInteractor();
186     virtual void layoutInteractorHorizontally();
187     virtual void layoutInteractorVertically();
188     virtual void layoutInteractorWithNoLabel();
189 
190     virtual const char *getComponentHelpTopic();
191 
192     //
193     // Drag and Drop related stuff
194     //
195     // Create the .net and .cfg files and the header string.
196     // return the names of the files.
197     //
198     virtual int decideToDrag (XEvent *);
199     virtual void dropFinish (long, int, unsigned char);
200     boolean createNetFiles (Network *, FILE *netf, char *cfgFile);
getDragDictionary()201     virtual Dictionary *getDragDictionary() { return Interactor::DragTypeDictionary; }
202     virtual boolean decodeDragType (int, char *, XtPointer *, unsigned long *, long );
203 
204     //
205     // Constructor:
206     //
207     Interactor(const char * name, InteractorInstance *ii);
208 
209 
210   public:
211     //
212     // Destructor:
213     //
214     ~Interactor();
215 
216 
217     //
218     // Set the displayed label of the interactor and do a layout if
219     // indicated to handle a significant change in label width.
220     //
221     virtual void setLabel(const char *labelString, boolean re_layout = TRUE);
222 
223     //
224     // The following are used to notify a control panel when an Interactor's
225     // status changes.  If it is selected or unselected the control
226     // panel needs to be notified.  Currently, notification is done
227     // through ControlPanel::handleInteractorInstanceStatusChange().
228     //
229     enum {
230                 InteractorSelected   = 1, // Interactor was just selected.
231                 InteractorDeselected = 2 // Interactor was just unselected.
232     };
233     virtual void setSelected(boolean state);
234 
235     //
236     // Default routines for determining the height and width of the
237     // this->interactivePart widget.
238     //
239     //virtual void getInteractivePartDimensions(Dimension *h, Dimension *w);
240 
241 
242     //
243     // Open the window for the default action (a double click) of this
244     // interactor;
245     //
246     virtual void openDefaultWindow();
247 
248     //
249     // Reset the resources of the widget based on a presumably new set
250     // of attributes.  The src_ii is the InteractorInstance that has
251     // initialiated the attribute change.  Some attributes (local or
252     // per interactor ones) may be ignored if the attribute change is
253     // initiated by a src_ii such that this->instance != src_ii.
254     // This should also include updating the displayed value.
255     // If major_change is TRUE, then the subclass may choose to unmanage
256     // itself while changes (presumably major) are made to it.
257     // handleInteractorStateChange() remanages the interactor root widget
258     // if it was unmanaged by handleInteractivePartStateChange().
259     //
260     virtual void handleInteractorStateChange(InteractorInstance *src_ii,
261 					boolean major_change);
262     virtual void handleInteractivePartStateChange(
263 				InteractorInstance *src_ii,
264 			 	boolean major_change) = 0;
265 
266     //
267     // Update the display values for an interactor;
268     // Called when an InteractorNode does a this->setOutputValue().
269     //
270     virtual void updateDisplayedInteractorValue(void) = 0;
271 
272     //
273     // Change the layout between horizontal and vertical.
274     //
275     void setVerticalLayout(boolean vertical = TRUE);
276     void setBlankLabelLayout(boolean blank_label = TRUE);
acceptsLayoutChanges()277     virtual boolean acceptsLayoutChanges()
278 	{ return ((this->currentLayout & WorkSpaceComponent::BlankLabel) == 0); }
279 
280     //
281     // Indicate that the interactor is selected.  Generally, this means
282     // highlighting.  This really only needs to be called when the
283     // control panel is first opened up, after that the workspace takes
284     // care of highlighting.  This can be called if the root widget
285     // has not yet been created, but the selection may not be reflected.
286     //
287     void indicateSelect(boolean selected);
288 
289     Network		*getNetwork();
290     Node		*getNode();
291     ControlPanel	*getControlPanel();
292 
293     //
294     // One time initialize for the class.
295     //
296     virtual void initialize();
297 
298     //
299     // Returns a pointer to the class name.
300     //
getClassName()301     const char* getClassName()
302     {
303 	return ClassInteractor;
304     }
305 
306     virtual boolean isA(Symbol classname);
307 };
308 
309 
310 #endif // _Interactor_h
311