/***********************************************************************/ /* Open Visualization Data Explorer */ /* (C) Copyright IBM Corp. 1989,1999 */ /* ALL RIGHTS RESERVED */ /* This code licensed under the */ /* "IBM PUBLIC LICENSE - Open Visualization Data Explorer" */ /***********************************************************************/ #include // InteractorNode.h - // // Definition for the InteractorNode class. // // The InteractorNode is represented by the StandIn that is visible in the // Editor work space. Each InteractorNode has a family of // InteractorInstance/Interactor pairs. This family is of unlimited size, // and different pairs can reside in different control panels. // The InteractorNode maintains a list of InteractorInstances (which in turn // reference their associated Interactor). // // We redefine this->openDefaultWindow() to (by default) open the control // panel that the InteractorInstance(s) are contained in. If you want // a different action for you derived class, redefine this. // // We also implement this->reflectStateChange() // which calls InteractorInstance::handleInteractorStateChange() on each of // the InteractorInstances in the list of associated instances. // // this->newInteractorInstance() and this->addInstance() are used during // .cfg file parsing to allocate a new InteractorInstance for (what is // usually) a derived class and add the instance to this->instanceList. // Redefine newInteractorInstance() if you need other than an // InteractorInstance class instance for your InteractorNode derived // class. // // Apart from the above we (re)define the standard parsing and printing // methods. We also define setOutputValues() so that all // InteractorInstances associated with this InteractorNode have their // displayed value updated by calling // this->setOutputAndOtherInteractorValues(). Typically, an Interactor // will change it's nodes output value which results in all other // Interactors having their displayed value change. // // All InteractorNodes are by default data-driven as defined by // DrivenNode::isDataDriven(). See the NondrivenInteractorNode sub-class // for interactor nodes that are not data-driven. A general discussion of // data-driven interactors follows... // // Data-driven interactors are interactors that have inputs and make an // executive module call and then expect a UImessage from that module // concerning the state of the Interactor (i.e. mininum, maximum, increment, // label...). this->Node::netPrintNode() determines if the InteractorNode is // data-driven with this->DrivenNode::expectingModuleMessage() via // this->DrivenNode::isDataDriven() and arranges // for this->execModuleMessageHandler() to be called when a message for // this InteractorNode is found. // // The following inputs are assumed at this level... // Input 1: Unique Id string identifying the instance of this node. // Input 2: Field/group input object. // Input 3: Current output value. // . . . // Input N: The label for this interactor (this is the last input). // // Because this class is derived from the ShadowedOutputNode class, // when this->setOutputValue() is called shadowing inputs are updated // to set to the values of any inputs that may be shadowing the given // output. Input to Output shadowing is defined in the virtual function // this->getShadowingInput(). A one to one mapping of input to output is // assumed in the overall architecture and by default output 1 is shadowed // by input 3 when this->isDataDriven() returns TRUE. // // // ////////////////////////////////////////////////////////////////////////////// #ifndef _InteractorNode_h #define _InteractorNode_h #include "defines.h" #include "ShadowedOutputNode.h" #include "InteractorStyle.h" typedef long Type; class Network; class InteractorInstance; class ComponentAttributes; class ControlPanel; // // Class name definition: // #define ClassInteractorNode "InteractorNode" // // InteractorNode class definition: // class InteractorNode : public ShadowedOutputNode { friend class ControlPanel; // Needs to be able to delete instances. friend class SetAttrDialog; // Needs to un/deferVisualNotification(). friend class InteractorInstance; // Needs direct access to instanceList. private: // // Private member data: // char* java_variable; protected: // // Protected member data: // // // Used by getInteractorLabel() so it can return a const char *. // char *lastInteractorLabel; // // numComponents is the value parsed from the .cfg file and may // be interpretted differently depending upon the derived class. // int numComponents; List instanceList; // List of InteractorInstances for this node. virtual boolean cfgParseInteractorComment(const char* comment, const char* filename, int lineno); virtual boolean cfgParseInstanceComment(const char* comment, const char* filename, int lineno); virtual boolean cfgParseLabelComment(const char* comment, const char* filename, int lineno); virtual boolean cfgPrintInteractor(FILE *f); virtual boolean cfgPrintInteractorComment(FILE *f); virtual boolean cfgPrintInteractorAuxInfo(FILE * /* f */) { return TRUE; }; virtual boolean cfgPrintInteractorInstances(FILE *f, PrintType dest); virtual boolean cfgPrintInstanceComment(FILE *f, InteractorInstance *ii); virtual boolean cfgPrintInstanceLabelComment(FILE *f, InteractorInstance *ii); virtual boolean cfgPrintInstanceAuxInfo(FILE * /* f */, InteractorInstance * /* ii */) { return TRUE; } boolean appendInstance(InteractorInstance *ii) { return this->instanceList.appendElement((void*)ii); } // // Get a new interactor instance for this class. // Derived classes can override this to allocated subclasses of // InteractorInstance which may be specific to the derived class. // For example, ScalarNode uses a ScalarInstance instead // of an InteractorInstance which incorporates local modes. // virtual InteractorInstance *newInteractorInstance(); // // Delete and free an instance from the list of instances. // This may be called by a ControlPanel. // boolean deleteInstance(InteractorInstance *ii); // // Create a new interactor instance (using newInteractorInstance()) // giving it the given position and style and assigning it to the given // ContorlPanel, if given. This includes adding the instance to the // control panels list of instances. // Returns the InteractorInstance on success, NULL otherwise. // InteractorInstance *addInstance(int x, int y, InteractorStyle *is, ControlPanel *cp = NULL, int width = 0, int height = 0); // // Get the index'th interactor instance for this Interactor. // index is 1 based. // InteractorInstance *getInstance(int index) { ASSERT(index > 0); return (InteractorInstance*) this->instanceList.getElement(index); } // // Called when a message is received from the executive after // this->ExecModuleMessageHandler() is registered in // this->Node::netPrintNode() to receive messages for this node. // We parse all the common information and then the class specific. // We return the number of items in the message. // virtual int handleNodeMsgInfo(const char *line); // // Parse the interactor specific info from an executive message. // Returns the number of attributes parsed. // virtual int handleInteractorMsgInfo(const char *line) = 0; // // Parse attributes that are common to all data-driven interactors. // Parses and sets the label from a message string. // Returns the number of recognized message items. // int handleCommonMsgInfo(const char *line); // // Update all interactor instances that may be based on the state of this // node. Among other times, this is called after receiving a message // from the executive. // virtual void reflectStateChange(boolean unmanage); // // Define the mapping of inputs that shadow outputs. // By default, all data driven interactors, have a single output that is // shadowed by the third input. // Returns an input index (greater than 1) or 0 if there is no shadowing // input for the given output index. // virtual int getShadowingInput(int output_index); // // Get the index of the label parameter. // Be default, it is always the last parameter. // virtual int getLabelParameterIndex(); // // Set all shadowing inputs to use the default value. // This is most likely used during initialization after setting the outputs // (which sets the shadowing inputs). // void setShadowingInputsDefaulting(boolean send = FALSE); // // Notify anybody that needs to know that a parameter has changed its arcs. // At this class level, we just check changes in output arcs that may // change the label associated with the Interactor. If it may have // changed the label, then we notify all instances with // notifyVisualsOfStateChange(). // virtual void ioParameterStatusChanged(boolean input, int index, NodeParameterStatusChange status); // // Print the script representation of the call for interactors. // For interactors, there is no executive call, unless we are being // data driven. The work done here is to determine if we are acting // as a data-driven interactor and then to do the correct action. // If we are not data-driven, return "" since there is no work for // the executive to do for us. // If we are data-driven, then we generate the call to the correct // executive module by calling the superclass' method. // virtual char *netNodeString(const char *prefix); // // Change the dimensionality of the vector; // At this level, we don't allow dimensionality changes so we always // return FALSE; // boolean changeDimensionality(int new_dim); virtual boolean doDimensionalityChange(int new_dim); #if 0 // 8/9/93 // // Determine if the given input parameter is writeable as an attribute. // virtual boolean isAttributeVisuallyWriteable(int input_index); #endif public: // // Constructor: // InteractorNode(NodeDefinition *nd, Network *net, int instnc); // // Destructor: // ~InteractorNode(); // // Return a pointer to a string representing the global name that can // be used to label interactors. This can be superseded by a local label // string maintained in InteractorInstance. // The algorithm we use is as follows... // If there are no output arcs or more than 1 use "Value:" // If there is a single output arc, use the name of the destination // node and parameter. // char *getOutputDerivedLabel(); virtual const char *getInteractorLabel(); // // Set the global label for all instances of this interactor node. // DrivenInteractors keep their labels in the label parameter. // If strip_quotes is TRUE, then remove leading and trail double quotes // which are expected to be present. // void saveInteractorLabel(const char *label, boolean strip_quotes = FALSE); // // Get the current type of the given output. // Be default, this is the type of current output value or if no value is // currently set, then the first (and only?) type in the parameters type // list. If an interactor can have different outputs, that class should // override this. // Type getTheCurrentOutputType(int index); // // Redefine this so that we call the super-class method and then // check for the input comment for the label parameter value (if we have // one). If we see the label parameter value then save it. // virtual boolean netParseComment(const char* comment, const char *file, int lineno); virtual boolean cfgParseComment(const char* comment, const char* filename, int lineno); // // Routine for printing the .cfg file contents for this interactor. // virtual boolean cfgPrintNode(FILE *f, PrintType dest); // // Get the number of instances for this interactor. // int getInstanceCount() { return instanceList.getSize(); } int getComponentCount() { return this->numComponents; } // // Calls setOutputAndOtherInteractorValues to update all interactor // instances. // virtual Type setOutputValue(int index, const char *value, Type t = DXType::UndefinedType, boolean send = TRUE); // // Indicates whether this node has outputs that can be remapped by the // server. // virtual boolean hasRemappableOutput(); // // Do what ever is necessary to enable/disable remapping of output values // by the server. // virtual void setOutputRemapping(boolean val); // // The default action for interactors is to open the control panels // associated with the instances. This overrides Node::openDefaultWindow() // virtual void openDefaultWindow(Widget parent); // // Let the caller of openDefaultWindow() know what kind of window she's getting. // This is intended for use in EditorWindow so that we can sanity check the number // of cdbs were going to open before kicking off the operation and so that we // don't question the user before opening large numbers of interactors. // A name describing the type of window can be written into window_name in order // to enable nicer warning messages. // virtual boolean defaultWindowIsCDB(char* window_name = NULL) { if (window_name) strcpy (window_name, "Interactor"); return FALSE; } // // If the node does not currently have any InteractorInstances, then // add them to the editor's/network's notion of the current control panel. // void openControlPanels(Widget parent); // // Does this node support dimensionality changes. // By default all interactors do NOT support this. // virtual boolean hasDynamicDimensionality(boolean ignoreDataDriven = FALSE); // // Determine if this node is a node of the given class // virtual boolean isA(Symbol classname); // // just like deleteInstance except don't delete ii, just remove it from the list. // boolean removeInstance (InteractorInstance *ii); // // Return TRUE if this node has state that will be saved in a .cfg file. // virtual boolean hasCfgState(); virtual boolean printAsJava(FILE* ); virtual boolean printJavaValue(FILE*); virtual const char* getJavaVariable(); virtual const char* getJavaNodeName() { return "ValueNode"; } // // Returns a pointer to the class name. // const char* getClassName() { return ClassInteractorNode; } }; #endif // _InteractorNode_h