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