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 // InteractorNode.h -
15 //
16 // Definition for the InteractorNode class.
17 //
18 // The InteractorNode is represented by the StandIn that is visible in the
19 // Editor work space.  Each InteractorNode has a family of
20 // InteractorInstance/Interactor pairs.  This family is of unlimited size,
21 // and different pairs can reside in different control panels.
22 // The InteractorNode maintains a list of InteractorInstances (which in turn
23 // reference their associated Interactor).
24 //
25 // We redefine this->openDefaultWindow() to (by default) open the control
26 // panel that the InteractorInstance(s) are contained in.  If you want
27 // a different action for you derived class, redefine this.
28 //
29 // We also implement this->reflectStateChange()
30 // which calls InteractorInstance::handleInteractorStateChange() on each of
31 // the InteractorInstances in the list of associated instances.
32 //
33 // this->newInteractorInstance() and this->addInstance() are used during
34 // .cfg file parsing to allocate a new InteractorInstance for (what is
35 // usually) a derived class and add the instance to this->instanceList.
36 // Redefine newInteractorInstance() if you need other than an
37 // InteractorInstance class instance for your InteractorNode derived
38 // class.
39 //
40 // Apart from the above we (re)define the standard parsing and printing
41 // methods.  We also define setOutputValues() so that all
42 // InteractorInstances  associated with this InteractorNode have their
43 // displayed value updated by calling
44 // this->setOutputAndOtherInteractorValues().  Typically, an Interactor
45 // will change it's nodes output value which results in all other
46 // Interactors having their displayed value change.
47 //
48 // All InteractorNodes are by default data-driven as defined by
49 // DrivenNode::isDataDriven().  See the NondrivenInteractorNode sub-class
50 // for interactor nodes that are not data-driven.  A general discussion of
51 // data-driven interactors follows...
52 //
53 // Data-driven interactors are interactors that have inputs and make an
54 // executive module call and then expect a UImessage from that module
55 // concerning the state of the Interactor (i.e. mininum, maximum, increment,
56 // label...).  this->Node::netPrintNode() determines if the InteractorNode is
57 // data-driven with this->DrivenNode::expectingModuleMessage() via
58 // this->DrivenNode::isDataDriven() and arranges
59 // for this->execModuleMessageHandler() to be called when a message for
60 // this InteractorNode is found.
61 //
62 // The following inputs are assumed at this level...
63 //      Input 1: Unique Id string identifying the instance of this node.
64 //      Input 2: Field/group input object.
65 //      Input 3: Current output value.
66 //         . . .
67 //      Input N: The label for this interactor (this is the last input).
68 //
69 // Because this class is derived from the ShadowedOutputNode class,
70 // when this->setOutputValue() is called shadowing inputs are updated
71 // to set to the values of any inputs that may be shadowing the given
72 // output.  Input to Output shadowing is defined in the virtual function
73 // this->getShadowingInput().  A one to one mapping of input to output is
74 // assumed in the overall architecture and by default output 1 is shadowed
75 // by input 3 when this->isDataDriven() returns TRUE.
76 //
77 //
78 //
79 //////////////////////////////////////////////////////////////////////////////
80 
81 #ifndef _InteractorNode_h
82 #define _InteractorNode_h
83 
84 
85 #include "ShadowedOutputNode.h"
86 #include "InteractorStyle.h"
87 
88 typedef long Type;
89 
90 class Network;
91 class InteractorInstance;
92 class ComponentAttributes;
93 class ControlPanel;
94 
95 //
96 // Class name definition:
97 //
98 #define ClassInteractorNode	"InteractorNode"
99 
100 //
101 // InteractorNode class definition:
102 //
103 class InteractorNode : public ShadowedOutputNode
104 {
105     friend class ControlPanel;	// Needs to be able to delete instances.
106     friend class SetAttrDialog; // Needs to un/deferVisualNotification().
107     friend class InteractorInstance; // Needs direct access to instanceList.
108 
109   private:
110     //
111     // Private member data:
112     //
113     char* java_variable;
114 
115   protected:
116     //
117     // Protected member data:
118     //
119 
120     //
121     // Used by getInteractorLabel() so it can return a const char *.
122     //
123     char 	*lastInteractorLabel;
124 
125     //
126     // numComponents is the value parsed from the .cfg file and may
127     // be interpretted differently depending upon the derived class.
128     //
129     int		numComponents;
130 
131     List	instanceList;	// List of InteractorInstances for this node.
132 
133     virtual boolean cfgParseInteractorComment(const char* comment,
134                 		const char* filename, int lineno);
135     virtual boolean cfgParseInstanceComment(const char* comment,
136                 		const char* filename, int lineno);
137     virtual boolean cfgParseLabelComment(const char* comment,
138                 		const char* filename, int lineno);
139 
140     virtual boolean cfgPrintInteractor(FILE *f);
141     virtual boolean cfgPrintInteractorComment(FILE *f);
cfgPrintInteractorAuxInfo(FILE *)142     virtual boolean cfgPrintInteractorAuxInfo(FILE * /* f */) { return TRUE; };
143     virtual boolean cfgPrintInteractorInstances(FILE *f, PrintType dest);
144     virtual boolean cfgPrintInstanceComment(FILE *f,
145 						 InteractorInstance *ii);
146     virtual boolean cfgPrintInstanceLabelComment(FILE *f,
147 						 InteractorInstance *ii);
cfgPrintInstanceAuxInfo(FILE *,InteractorInstance *)148     virtual boolean cfgPrintInstanceAuxInfo(FILE * /* f */,
149 						InteractorInstance * /* ii */)
150 			{ return TRUE; }
151 
appendInstance(InteractorInstance * ii)152     boolean	appendInstance(InteractorInstance *ii)
153 		  { return this->instanceList.appendElement((void*)ii); }
154     //
155     // Get a new interactor instance for this class.
156     // Derived classes can override this to allocated subclasses of
157     // InteractorInstance which may be specific to the derived class.
158     // For example, ScalarNode uses a ScalarInstance instead
159     // of an InteractorInstance which incorporates local modes.
160     //
161     virtual	InteractorInstance *newInteractorInstance();
162 
163 
164     //
165     // Delete and free an instance from the list of instances.
166     // This may be called by a ControlPanel.
167     //
168     boolean	deleteInstance(InteractorInstance *ii);
169 
170     //
171     // Create a new interactor instance (using newInteractorInstance())
172     // giving it the given position and style and assigning it to the given
173     // ContorlPanel, if given.  This includes adding the instance to the
174     // control panels list of instances.
175     // Returns the InteractorInstance on success, NULL otherwise.
176     //
177     InteractorInstance *addInstance(int x, int y,
178 				InteractorStyle *is,
179 				ControlPanel *cp = NULL,
180 				int width = 0, int height = 0);
181     //
182     //  Get the index'th interactor instance for this Interactor.
183     //  index is 1 based.
184     //
getInstance(int index)185     InteractorInstance *getInstance(int index)
186 		{
187 		    ASSERT(index > 0);
188 		    return (InteractorInstance*)
189 				this->instanceList.getElement(index);
190 		}
191     //
192     // Called when a message is received from the executive after
193     // this->ExecModuleMessageHandler() is registered in
194     // this->Node::netPrintNode() to receive messages for this node.
195     // We parse all the common information and then the class specific.
196     // We return the number of items in the message.
197     //
198     virtual int handleNodeMsgInfo(const char *line);
199 
200 
201     //
202     // Parse the interactor specific info from an executive message.
203     // Returns the number of attributes parsed.
204     //
205     virtual int  handleInteractorMsgInfo(const char *line) = 0;
206 
207     //
208     // Parse attributes that are common to all data-driven interactors.
209     // Parses and sets the label from a message string.
210     // Returns the number of recognized message items.
211     //
212     int handleCommonMsgInfo(const char *line);
213 
214     //
215     // Update all interactor instances that may be based on the state of this
216     // node.   Among other times, this is called after receiving a message
217     // from the executive.
218     //
219     virtual void reflectStateChange(boolean unmanage);
220 
221     //
222     // Define the mapping of inputs that shadow outputs.
223     // By default, all data driven interactors, have a single output that is
224     // shadowed by the third input.
225     // Returns an input index (greater than 1) or 0 if there is no shadowing
226     // input for the given output index.
227     //
228     virtual int getShadowingInput(int output_index);
229 
230     //
231     // Get the index of the label parameter.
232     // Be default, it is always the last parameter.
233     //
234     virtual int getLabelParameterIndex();
235 
236     //
237     // Set all shadowing inputs to use the default value.
238     // This is most likely used during initialization after setting the outputs
239     // (which sets the shadowing inputs).
240     //
241     void setShadowingInputsDefaulting(boolean send = FALSE);
242 
243     //
244     // Notify anybody that needs to know that a parameter has changed its arcs.
245     // At this class level, we just check changes in output arcs that may
246     // change the label associated with the Interactor.  If it may have
247     // changed the label, then we notify all instances with
248     // notifyVisualsOfStateChange().
249     //
250     virtual void ioParameterStatusChanged(boolean input, int index,
251 				NodeParameterStatusChange status);
252 
253     //
254     // Print the script representation of the call for interactors.
255     // For interactors, there is no executive call, unless we are being
256     // data driven.  The work done here is to determine if we are acting
257     // as a data-driven interactor and then to do the correct action.
258     // If we are not data-driven, return "" since there is no work for
259     // the executive to do for us.
260     // If we are data-driven, then we generate the call to the correct
261     // executive module by calling the superclass' method.
262     //
263     virtual char *netNodeString(const char *prefix);
264 
265     //
266     // Change the dimensionality of the vector;
267     // At this level, we don't allow dimensionality changes so we always
268     // return FALSE;
269     //
270     boolean changeDimensionality(int new_dim);
271     virtual boolean doDimensionalityChange(int new_dim);
272 
273 #if 0	// 8/9/93
274     //
275     // Determine if the given input parameter is writeable as an attribute.
276     //
277     virtual boolean isAttributeVisuallyWriteable(int input_index);
278 #endif
279 
280   public:
281     //
282     // Constructor:
283     //
284     InteractorNode(NodeDefinition *nd, Network *net, int instnc);
285 
286     //
287     // Destructor:
288     //
289     ~InteractorNode();
290 
291     //
292     // Return a pointer to a string representing the global name that can
293     // be used to label interactors.   This can be superseded by a local label
294     // string maintained in InteractorInstance.
295     // The algorithm we use is as follows...
296     //  If there are no output arcs  or more than 1 use "Value:"
297     //	If there is a single output arc, use the name of the destination
298     //	    node and parameter.
299     //
300     char *getOutputDerivedLabel();
301     virtual const char *getInteractorLabel();
302 
303     //
304     // Set the global label for all instances of this interactor node.
305     // DrivenInteractors keep their labels in the label parameter.
306     // If strip_quotes is TRUE, then remove leading and trail double quotes
307     // which are expected to be present.
308     //
309     void saveInteractorLabel(const char *label, boolean strip_quotes = FALSE);
310 
311 
312     //
313     // Get the current type of the given output.
314     // Be default, this is the type of current output value or if no value is
315     // currently set, then the first (and only?) type in the parameters type
316     // list. If an interactor can have different outputs, that class should
317     // override this.
318     //
319     Type  getTheCurrentOutputType(int index);
320 
321     //
322     // Redefine this so that we call the super-class method and then
323     // check for the input comment for the label parameter value (if we have
324     // one).  If we see the label parameter value then save it.
325     //
326     virtual boolean netParseComment(const char* comment,
327                                 const char *file, int lineno);
328 
329     virtual boolean cfgParseComment(const char* comment,
330                 		const char* filename, int lineno);
331 
332     //
333     // Routine for printing the .cfg file contents for this interactor.
334     //
335     virtual boolean cfgPrintNode(FILE *f, PrintType dest);
336 
337 
338     //
339     // Get the number of instances for this interactor.
340     //
getInstanceCount()341     int	getInstanceCount()	{ return instanceList.getSize(); }
342 
getComponentCount()343     int getComponentCount()	{ return this->numComponents; }
344 
345     //
346     // Calls setOutputAndOtherInteractorValues to update all interactor
347     // instances.
348     //
349     virtual Type setOutputValue(int index,
350                                 const char *value,
351                                 Type t = DXType::UndefinedType,
352                                 boolean send = TRUE);
353 
354 
355     //
356     // Indicates whether this node has outputs that can be remapped by the
357     // server.
358     //
359     virtual boolean hasRemappableOutput();
360     //
361     // Do what ever is necessary to enable/disable remapping of output values
362     // by the server.
363     //
364     virtual void setOutputRemapping(boolean val);
365 
366     //
367     // The default action for interactors is to open the control panels
368     // associated with the instances.  This overrides Node::openDefaultWindow()
369     //
370     virtual void openDefaultWindow(Widget parent);
371 
372     //
373     // Let the caller of openDefaultWindow() know what kind of window she's getting.
374     // This is intended for use in EditorWindow so that we can sanity check the number
375     // of cdbs were going to open before kicking off the operation and so that we
376     // don't question the user before opening large numbers of interactors.
377     // A name describing the type of window can be written into window_name in order
378     // to enable nicer warning messages.
379     //
380     virtual boolean defaultWindowIsCDB(char* window_name = NULL)
381 	{ if (window_name) strcpy (window_name, "Interactor"); return FALSE; }
382     //
383     // If the node does not currently have any InteractorInstances, then
384     // add them to the editor's/network's notion of the current control panel.
385     //
386     void openControlPanels(Widget parent);
387 
388     //
389     // Does this node support dimensionality changes.
390     // By default all interactors do NOT support this.
391     //
392     virtual boolean hasDynamicDimensionality(boolean ignoreDataDriven = FALSE);
393 
394     //
395     // Determine if this node is a node of the given class
396     //
397     virtual boolean isA(Symbol classname);
398 
399 
400     //
401     // just like deleteInstance except don't delete ii, just remove it from the list.
402     //
403     boolean removeInstance (InteractorInstance *ii);
404 
405     //
406     // Return TRUE if this node has state that will be saved in a .cfg file.
407     //
408     virtual boolean hasCfgState();
409 
410     virtual boolean printAsJava(FILE* );
411     virtual boolean printJavaValue(FILE*);
412     virtual const char* getJavaVariable();
getJavaNodeName()413     virtual const char* getJavaNodeName() { return "ValueNode"; }
414 
415     //
416     // Returns a pointer to the class name.
417     //
getClassName()418     const char* getClassName()
419     {
420 	return ClassInteractorNode;
421     }
422 };
423 
424 
425 #endif // _InteractorNode_h
426