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 //#include <Xm/DialogS.h>
14 
15 #include "DXApplication.h"
16 #include "SequencerWindow.h"
17 #include "SequencerNode.h"
18 
19 #include "../widgets/VCRControl.h"
20 
21 Boolean SequencerWindow::ClassInitialized = FALSE;
22 
23 String SequencerWindow::DefaultResources[] = {
24 	".title:			      Sequence Control",
25         ".iconName:                           Sequencer",
26 	"*XmVCRControl.currentColor:          #7e7ec9c90000",
27 	"*XmVCRControl.nextColor:             #ffffffff7e7e",
28         "*XmFrameControl.accelerators:        #augment\n"
29         "<Key>Return:                         BulletinBoardReturn()",
30 	NULL
31 };
32 
createWorkArea(Widget parent)33 Widget SequencerWindow::createWorkArea(Widget parent)
34 {
35 
36     SequencerNode *snode = this->node;
37 
38     this->vcr = XtVaCreateManagedWidget("VCR",xmVCRControlWidgetClass, parent,
39         XmNwidth,                280,
40         XmNheight,               80,
41 	XmNresizePolicy,	 XmRESIZE_ANY,
42 	XmNminimum,		 snode->getMinimumValue(),
43 	XmNmaximum,		 snode->getMaximumValue(),
44 	XmNstart,		 snode->getStartValue(),
45 	XmNstop,		 snode->getStopValue(),
46 	XmNcurrent,		 snode->current,
47 	XmNcurrentVisible,	 snode->current_defined,
48 	XmNnext,		 snode->next,
49 	XmNincrement,		 snode->getDeltaValue(),
50 	XmNloopButtonState,	 snode->loop,
51 	XmNstepButtonState,	 snode->step,
52 	XmNpalindromeButtonState,snode->palindrome,
53 	NULL);
54 
55     //
56     // Install the help callback for the vcr
57     //
58     this->installComponentHelpCallback(this->vcr);
59 
60     //
61     // Install the correct state from the node.
62     //
63     this->handleStateChange(FALSE);
64 
65 #if 0
66     //
67     // Add some callbacks.
68     //
69     XtAddCallback(shell,
70 		      XmNpopdownCallback,
71 		      (XtCallbackProc)SequencerWindow_PopdownCB,
72 		      (XtPointer)this);
73 #endif
74 
75     XtAddCallback(this->vcr,
76 		      XmNactionCallback,
77 		      (XtCallbackProc)SequencerWindow_VcrCB,
78 		      (XtPointer)this);
79 
80     XtAddCallback(this->vcr,
81 		      XmNframeCallback,
82 		      (XtCallbackProc)SequencerWindow_FrameCB,
83 		      (XtPointer)this);
84 
85     return this->vcr;
86 }
87 
88 
SequencerWindow(SequencerNode * node)89 SequencerWindow::SequencerWindow(SequencerNode* node)
90                        		: DXWindow("sequencerWindow", FALSE, FALSE)
91 {
92     this->node = node;
93     this->vcr = NULL;
94     this->handlingStateChange = FALSE;
95 
96     //
97     // Install the default resources for THIS class (not the derived classes)
98     //
99     if (NOT SequencerWindow::ClassInitialized)
100     {
101 	ASSERT(theApplication);
102         SequencerWindow::ClassInitialized = TRUE;
103 	this->installDefaultResources(theApplication->getRootWidget());
104     }
105 }
106 
107 
~SequencerWindow()108 SequencerWindow::~SequencerWindow()
109 {
110 
111 #if 0
112     XtRemoveCallback(this->getRootWidget(),
113 		      XmNpopdownCallback,
114 		      (XtCallbackProc)SequencerWindow_PopdownCB,
115 		      (XtPointer)this);
116 #endif
117 
118 }
119 
120 
121 //
122 // Install the default resources for this class.
123 //
installDefaultResources(Widget baseWidget)124 void SequencerWindow::installDefaultResources(Widget baseWidget)
125 {
126     this->setDefaultResources(baseWidget,
127 			SequencerWindow::DefaultResources);
128     this->DXWindow::installDefaultResources(baseWidget);
129 }
130 
reset()131 void SequencerWindow::reset()
132 {
133     Arg    arg[3];
134 
135     XtSetArg(arg[0], XmNforwardButtonState,  FALSE);
136     XtSetArg(arg[1], XmNbackwardButtonState, FALSE);
137     XtSetArg(arg[2], XmNframeSensitive,      TRUE);
138 
139     XtSetValues(this->vcr, arg, 3);
140 
141 }
142 
mapRaise()143 void SequencerWindow::mapRaise()
144 {
145         XMapRaised(XtDisplay(this->getRootWidget()),
146                    XtWindow(this->getRootWidget()));
147 	XtManageChild(this->vcr);
148 
149 }
150 
151 
SequencerWindow_VcrCB(Widget widget,XtPointer clientData,XtPointer callData)152 extern "C" void SequencerWindow_VcrCB(Widget    widget,
153                                 XtPointer clientData,
154                                 XtPointer callData)
155 {
156     VCRCallbackStruct* vcr = (VCRCallbackStruct*) callData;
157 
158     switch (vcr->action)
159     {
160 	case VCR_FORWARD:
161 	case VCR_BACKWARD:
162 
163     	     theDXApplication->getExecCtl()->vcrExecute(vcr->action);
164 	     break;
165 
166 	default:
167 
168     	     theDXApplication->getExecCtl()->vcrCommand(vcr->action,vcr->on);
169     }
170 }
171 
SequencerWindow_FrameCB(Widget widget,XtPointer clientData,XtPointer callData)172 extern "C" void SequencerWindow_FrameCB(Widget    widget,
173                                 XtPointer clientData,
174                                 XtPointer callData)
175 {
176     SequencerWindow *dialog = (SequencerWindow*) clientData;
177     dialog->frameCallback(callData);
178 }
179 
frameCallback(XtPointer callData)180 void SequencerWindow::frameCallback(XtPointer callData)
181 {
182     char   command[64];
183     Arg    arg[3];
184 
185     SequencerNode *node = (SequencerNode*) this->node;
186     VCRCallbackStruct* vcr = (VCRCallbackStruct*) callData;
187 
188     //
189     // Turn off this call back when installing state which we're sure
190     // is consistennt (i.e. min >= start >= max and min >= stop >= max and
191     // start <= stop). Also see the comment in this->handleStateChange().
192     //
193     if (this->handlingStateChange)
194 	return;
195 
196     switch (vcr->which)
197     {
198       case XmCR_NEXT:
199 	node->next = vcr->detent;
200         sprintf(command, "@nextframe = %d;\n", node->next);
201         break;
202 
203       case XmCR_START:
204 	node->setStartValue(vcr->detent);
205         sprintf(command, "@startframe = %d;\n", node->getStartValue());
206         break;
207 
208       case XmCR_STOP:
209 	node->setStopValue(vcr->detent);
210         sprintf(command, "@endframe = %d;\n", node->getStopValue());
211         break;
212 
213       case XmCR_INCREMENT:
214 	node->setDeltaValue(vcr->detent);
215         sprintf(command, "@deltaframe = %d;\n", node->getDeltaValue());
216         break;
217 
218       case XmCR_MIN:
219 	node->setMinimumValue(vcr->value);
220 	/*
221 	 * If the minimum value has been changed, change the start
222 	 * value as well.
223 	 */
224 	node->setStartValue(vcr->value);
225 	XtSetArg(arg[0], XmNstart, node->getStartValue());
226 	XtSetValues(this->vcr, arg, 1);
227 
228         sprintf(command, "@startframe = %d;\n", node->getStartValue());
229         break;
230 
231       case XmCR_MAX:
232 	node->setMaximumValue(vcr->value);
233 	/*
234 	 * If the maximum value has been changed, change the stop
235 	 * value as well.
236 	 */
237 	node->setStopValue(vcr->value);
238 	XtSetArg(arg[0], XmNstop, node->getStopValue());
239 	XtSetValues(this->vcr, arg, 1);
240 
241         sprintf(command, "@endframe = %d;\n", node->getStopValue());
242         break;
243 
244       default:
245 
246         ASSERT(FALSE);
247         break;
248     }
249 
250     /*
251      * Send the command.
252      */
253     theDXApplication->getExecCtl()->vcrFrameSet(command);
254 
255 }
256 
SequencerWindow_PopdownCB(Widget widget,XtPointer clientData,XtPointer callData)257 extern "C" void SequencerWindow_PopdownCB(Widget    widget,
258                                 XtPointer clientData,
259                                 XtPointer callData)
260 {
261 #if 0
262     int i;
263     Arg arg[1];
264 
265     ASSERT(clientData);
266 
267     SequencerWindow *data = (SequencerWindow*) clientData;
268 
269     XtSetArg(arg[0], XmNcountButtonState, False);
270     XtSetValues(data->vcr, arg, 1);
271 
272 #endif
273 }
274 
275 //
276 // Update all state of the VCR with info from the Node.
277 //
handleStateChange(boolean unmanage)278 void SequencerWindow::handleStateChange(boolean unmanage)
279 {
280     SequencerNode *snode = this->node;
281 
282     if (!this->vcr)
283 	return;
284 
285     //
286     // Turn off the FrameCB callback when installing state which we're sure
287     // is consistent (i.e. min >= start >= max and min >= stop >= max and
288     // start <= stop). Specifically, we do this because when we are changing
289     // the range of min and max the vcr wants to make callbacks adjusting
290     // its internal start and stop values to be within range of the new
291     // min and max.  For example, assume that min==start and max==stop, then
292     // when moving from min=6, max=8 to min=2, max=4, the vcr causes
293     // callbacks on start=4, next=4 and stop=4 when installing the new min
294     // and max, but before the new start and stop are installed.  The
295     // problem is that it is clamping start to 4 (the new max), which does
296     // not seem unreasonable since the old start was greater than the new max.
297     // So, to get around this, we just turn off the FrameCB when installing
298     // this state. NOTE, that this assumes the executive has the same values
299     // that we are installing, otherwise the executive and the vcr get out
300     // of sync.
301     //
302     this->handlingStateChange = TRUE;
303 
304     XtVaSetValues(this->vcr,
305 	XmNminimum,		snode->getMinimumValue(),
306 	XmNmaximum,		snode->getMaximumValue(),
307 	NULL);
308 
309     XtVaSetValues(this->vcr,
310 	XmNstart,		snode->getStartValue(),
311 	XmNstop,		snode->getStopValue(),
312 	XmNincrement,		snode->getDeltaValue(),
313 	XmNcurrent,		snode->current,
314 	XmNcurrentVisible,	snode->current_defined,
315 	XmNnext,		snode->next,
316 	XmNminSensitive,	snode->isMinimumVisuallyWriteable(),
317 	XmNmaxSensitive,	snode->isMaximumVisuallyWriteable(),
318 	XmNincSensitive,	snode->isDeltaVisuallyWriteable(),
319         //
320         // Set the button states.  This is required for DXLink
321         //
322         XmNstepButtonState,             snode->isStepMode(),
323         XmNloopButtonState,             snode->isLoopMode(),
324         XmNpalindromeButtonState,       snode->isPalindromeMode(),
325 
326         NULL);
327 
328     this->handlingStateChange = FALSE;
329 }
330 //
331 // Disable the Frame control.
332 //
disableFrameControl()333 void SequencerWindow::disableFrameControl()
334 {
335     if (!this->vcr)
336 	return;
337 
338     XtVaSetValues(this->vcr, XmNframeSensitive,      False, NULL);
339 }
340 //
341 // Enable the Frame control.
342 //
enableFrameControl()343 void SequencerWindow::enableFrameControl()
344 {
345     if (!this->vcr)
346 	return;
347 
348     XtVaSetValues(this->vcr, XmNframeSensitive,      True, NULL);
349 }
350 //
351 // Set the buttons that indicate which way the sequencer is playing.
352 //
setPlayDirection(SequencerDirection direction)353 void SequencerWindow::setPlayDirection(SequencerDirection direction)
354 {
355     if (!this->vcr)
356 	return;
357 
358     switch (direction) {
359 	case SequencerNode::Directionless:
360 	    XtVaSetValues(this->vcr,
361 			XmNforwardButtonState,  False,
362 			XmNbackwardButtonState, False,
363 			NULL);
364 	break;
365 	case SequencerNode::ForwardDirection:
366 	    XtVaSetValues(this->vcr,
367 			XmNforwardButtonState,  True,
368 			XmNbackwardButtonState, False,
369 			NULL);
370 	break;
371 	case SequencerNode::BackwardDirection:
372 	    XtVaSetValues(this->vcr,
373 			XmNforwardButtonState,  False,
374 			XmNbackwardButtonState, True,
375 			NULL);
376 	break;
377 	default:
378 	    ASSERT(0);
379     }
380 
381 }
382 //
383 // Dis/enable frame control and then call the super class method.
384 //
beginExecution()385 void SequencerWindow::beginExecution()
386 {
387     this->disableFrameControl();
388     this->DXWindow::beginExecution();
389 }
standBy()390 void SequencerWindow::standBy()
391 {
392     this->enableFrameControl();
393     this->DXWindow::standBy();
394 }
endExecution()395 void SequencerWindow::endExecution()
396 {
397     this->enableFrameControl();
398     this->DXWindow::endExecution();
399 }
400 
401 
402 //
403 // Control the startup state of the window thru SequencerNode
404 // Startup values are maintained on our behalf by both DXWindow and
405 // SequencerNode.  It's possible that the 2 values will disagree, but
406 // SequencerNode must have one so that Network can determine the
407 // necessity of putting up the vcr.
408 //
manage()409 void SequencerWindow::manage()
410 {
411     this->DXWindow::manage();
412     this->setStartup(TRUE);
413 }
414 
unmanage()415 void SequencerWindow::unmanage()
416 {
417     this->DXWindow::unmanage();
418     this->setStartup(FALSE);
419 }
420 
setStartup(boolean flag)421 void SequencerWindow::setStartup (boolean flag)
422 {
423     this->DXWindow::setStartup(flag);
424     this->node->setStartup(flag);
425 }
426