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