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
15 #include <Xm/Xm.h>
16 #include <Xm/BulletinB.h>
17 #include <Xm/Form.h>
18 #include <Xm/DrawingA.h>
19 #include <Xm/Label.h>
20 #include <Xm/DragDrop.h>
21 #include <X11/Xatom.h>
22
23
24 #include "XmUtility.h"
25 #include "Interactor.h"
26 #include "InteractorInstance.h"
27 #include "../widgets/WorkspaceW.h"
28 #include "../widgets/XmDX.h"
29 #include "ControlPanel.h"
30 #include "ControlPanelWorkSpace.h"
31 #include "Network.h"
32 #include "DXStrings.h"
33 #include "DXApplication.h"
34
35 #include "ntractor.bm"
36 #include "ntractormask.bm"
37
38 boolean Interactor::InteractorClassInitialized = FALSE;
39 Widget Interactor::DragIcon;
40
41 #if defined(aviion) || defined(alphax)
42 // This constant exists in ToggleInteractor.C also, so if you make a change
43 // then dupe it there.
44 #define XMSTRING_COMPARE_IS_BROKEN
45 #endif
46
47 #define DXXOFFSET "DX_XOFFSET"
48 #define DXYOFFSET "DX_YOFFSET"
49
50 //
51 // This is the value that specifies the default thickness of the white
52 // border around the interactor (not the decorators).
53 // Use the constant as a default value for HiLites.
54 //
55 // If you change HiLites either thru a change to OFFSET or a change to
56 // dxui.interactorHighlight, you also affect the size of the interactor.
57 #define OFFSET 2
58 static int HiLites = OFFSET + 1;
59
60 String Interactor::DefaultResources[] =
61 {
62 "*borderWidth: 0",
63 ".shadowType: SHADOW_OUT",
64 ".resizePolicy: XmRESIZE_ANY",
65 "*interactive_form.resizePolicy: XmRESIZE_ANY",
66 ".shadowThickness: 1",
67 ".marginWidth: 1",
68 ".marginHeight: 1",
69 ".interactor_label.marginWidth: 1",
70 ".interactor_label.marginHeight: 0",
71 ".interactor_label.marginLeft: 1",
72 ".interactor_label.marginBottom: 1",
73 ".interactor_label.marginTop: 1",
74 ".interactor_label.marginRight: 1",
75 NUL(char*)
76 };
77
78 Dictionary* Interactor::DragTypeDictionary = new Dictionary;
79
Interactor(const char * name,InteractorInstance * ii)80 Interactor::Interactor(const char * name, InteractorInstance *ii) :
81 WorkSpaceComponent(name, FALSE),
82 DXDragSource(PrintCPBuffer)
83 {
84 this->interactorInstance = ii;
85 this->label = this->customPart = NUL(Widget);
86 this->currentLayout = ii->isVerticalLayout()?WorkSpaceComponent::VerticalUnset:
87 WorkSpaceComponent::HorizontalUnset;
88 this->drag_drop_wpid = 0;
89 }
90
~Interactor()91 Interactor::~Interactor()
92 {
93 if (this->drag_drop_wpid) XtRemoveWorkProc(this->drag_drop_wpid);
94 }
95
96 //
97 // Change any global attributes and then ask the derived class to
98 // change the attributes of the interactive part.
99 //
handleInteractorStateChange(InteractorInstance * src_ii,boolean major_change)100 void Interactor::handleInteractorStateChange(
101 InteractorInstance *src_ii, boolean major_change)
102 {
103 int userw, userh, curw, curh;
104
105 this->handleInteractivePartStateChange(src_ii, FALSE);
106
107 #if 0
108 //
109 // If the current label is different from the new one, then set it.
110 // Otherwise don't since it may cause the Interactor 'flash' on the
111 // control panel.
112 // FIXME: should do the same filtering that this->setLabel() does.
113 //
114 XmString xms;
115 char *curr_label;
116 const char *new_label = this->interactorInstance->getInteractorLabel();
117 XtVaGetValues(this->label, XmNlabelString, &xms, NULL);
118 // The charset must match what was used when the XmString was created.
119 XmStringGetLtoR(xms, "bold", &curr_label);
120 if (!EqualString(curr_label,new_label))
121 this->setLabel(new_label, FALSE);
122 delete curr_label;
123 XmStringFree(xms);
124 #else
125 // setLabel does nothing if oldlabel == newlabel
126 const char *new_label = this->interactorInstance->getInteractorLabel();
127 this->setLabel(new_label, FALSE);
128 #endif
129
130 //
131 // Remanage the interactor if the subclass'
132 // handleInteractivePartStateChange() method unmanaged it.
133 //
134 if (!this->isManaged())
135 this->manage();
136
137 //
138 // Growing and shrinking is a good thing, but don't get smaller than
139 // the most recent user specified dimensions.
140 //
141 if (this->isUserSizeSet()) {
142 this->getUserDimensions (&userw, &userh);
143 this->GetDimensions (this->getRootWidget(), &curh, &curw);
144 if ((curh!=userh) || (curw!=userw)) {
145 Boolean avr = True, ahr = True;
146 curw = MAX(curw, userw); curh = MAX(curh, userh);
147 XtVaGetValues (this->getRootWidget(), XmNallowVerticalResizing, &avr,
148 XmNallowHorizontalResizing, &ahr, NULL);
149 if (avr) this->setXYSize (UIComponent::UnspecifiedDimension, curh);
150 if (ahr) this->setXYSize (curw, UIComponent::UnspecifiedDimension);
151 }
152 }
153 }
154
155
initialize()156 void Interactor::initialize()
157 {
158 //
159 // Initialize default resources (once only).
160 //
161 if (NOT Interactor::InteractorClassInitialized)
162 {
163 Interactor::InteractorClassInitialized = TRUE;
164 Interactor::DragIcon =
165 this->createDragIcon(ntractor_width, ntractor_height,
166 (char *)ntractor_bits,
167 (char *)ntractormask_bits);
168
169 HiLites = OFFSET + 1;
170 #if GOING_OVERBOARD
171 Display *d = theApplication->getDisplay();
172 char *cp = XGetDefault (d, "dxui", "interactorHighlight");
173 // don't modify cp
174 if ((cp) && (cp[0])) {
175 sscanf (cp, "%d", &HiLites);
176 }
177 #endif
178
179 if ((theDXApplication->appAllowsRWConfig())&&
180 (theDXApplication->appAllowsSavingNetFile()) &&
181 (theDXApplication->appAllowsSavingCfgFile()) &&
182 (theDXApplication->appAllowsPanelEdit())) {
183 this->addSupportedType (Interactor::Modules, DXINTERACTORS, TRUE);
184 }
185 if (theDXApplication->appAllowsPanelEdit())
186 this->addSupportedType (Interactor::Trash, DXTRASH, FALSE);
187 }
188 }
189
190
setSelected(boolean state)191 void Interactor::setSelected (boolean state)
192 {
193 InteractorInstance *ii = this->interactorInstance;
194
195 if (state) ii->setSelected();
196 else ii->clrSelected();
197 this->WorkSpaceComponent::setSelected(state);
198 }
199
200 //
201 // Set the displayed label of the interactor
202 //
setLabel(const char * labelString,boolean)203 void Interactor::setLabel(const char *labelString, boolean )
204 {
205 XmStringContext cxt;
206 char *text, *tag;
207 XmStringDirection dir;
208 Boolean sep;
209 unsigned char rp;
210 int i, linesNew, linesOld;
211 XmString oldXmStr = NULL;
212
213 if(NOT this->label)
214 return;
215
216 linesNew = linesOld = 1;
217 XtVaGetValues (this->label, XmNlabelString, &oldXmStr, NULL);
218 ASSERT(oldXmStr);
219
220 char *filtered = WorkSpaceComponent::FilterLabelString (labelString);
221 for (i=0; filtered[i]!='\0'; i++) if (filtered[i]=='\n') linesNew++;
222
223 #if !defined(XMSTRING_COMPARE_IS_BROKEN)
224 // For efficiency only
225 XmString tmpXmStr = XmStringCreateLtoR (filtered, "canvas");
226 if (XmStringCompare (tmpXmStr, oldXmStr)) {
227 XmStringFree (tmpXmStr);
228 if (filtered) delete filtered;
229 XmStringFree(oldXmStr);
230 return ;
231 }
232 XmStringFree (tmpXmStr);
233 #endif
234
235 if (XmStringInitContext (&cxt, oldXmStr)) {
236 while (XmStringGetNextSegment (cxt, &text, &tag, &dir, &sep)) {
237 if (sep) linesOld++;
238 XtFree(text);
239 if (tag) XtFree(tag);
240 }
241 XmStringFreeContext(cxt);
242 }
243 XmStringFree(oldXmStr);
244
245 // toggle XmNresizePolicy so that the interactor doesn't snap back
246 // to a reasonable size. If the old string is taller/shorter than the new string
247 // then let it change.
248
249 if (linesNew == linesOld) {
250 XtVaGetValues (this->getRootWidget(), XmNresizePolicy, &rp, NULL);
251 XtVaSetValues (this->getRootWidget(), XmNresizePolicy, XmRESIZE_GROW, NULL);
252 } else {
253 this->resetUserDimensions();
254 }
255
256 if ((!filtered)||(!filtered[0])||(!strlen(filtered))) {
257 this->setBlankLabelLayout(TRUE);
258 } else {
259 this->setBlankLabelLayout(FALSE);
260 this->WorkSpaceComponent::SetLabelResource(this->label, labelString);
261 }
262 delete filtered;
263
264 if (linesNew == linesOld)
265 XtVaSetValues (this->getRootWidget(), XmNresizePolicy, rp, NULL);
266 }
267
268 void
openDefaultWindow()269 Interactor::openDefaultWindow() {this->interactorInstance->openSetAttrDialog();}
270
271 //
272 // Build an interactor widget tree.
273 //
createInteractor()274 void Interactor::createInteractor()
275 {
276 int n,x,y;
277 Arg wargs[30];
278 const char *labelString;
279 Widget parent;
280 InteractorInstance *ii = this->interactorInstance;
281
282 if (NOT Interactor::InteractorClassInitialized) this->Interactor::initialize();
283
284 this->workSpace = ii->getControlPanel()->getWorkSpace();
285 parent = this->workSpace->getRootWidget();
286 ASSERT(parent);
287
288 //
289 // Create the outermost frame.
290 //
291 ii->getXYPosition(&x,&y);
292
293 n = 0;
294 XtSetArg(wargs[n], XmNx, x); n++;
295 XtSetArg(wargs[n], XmNy, y); n++;
296 XtSetArg(wargs[n], XmNuserData, (XtPointer)ii); n++;
297 Widget standInRoot = XmCreateForm(parent, this->name, wargs, n);
298 this->setRootWidget(standInRoot);
299 this->setDragWidget(standInRoot);
300 this->setDragIcon(Interactor::DragIcon);
301 this->developerStyle = this->getControlPanel()->isDeveloperStyle();
302
303
304 //
305 // Restore width,height. By checking allow{Vertical,Horizontal}Resizing
306 // we're ignoring dimensions which aren't user configurable. That way
307 // we can read in .cfg files from other versions of dx without making
308 // crazy looking interactors. We always get the space we need.
309 //
310 int width = 0;
311 int height = 0;
312 ii->getXYSize(&width,&height);
313 Boolean avr = True, ahr = True;
314 XtVaGetValues (this->getRootWidget(),
315 XmNallowVerticalResizing, &avr,
316 XmNallowHorizontalResizing, &ahr,
317 NULL);
318 if ((!avr)||(!height)) height = UIComponent::UnspecifiedDimension;
319 if ((!ahr)||(!width)) width = UIComponent::UnspecifiedDimension;
320 if ((avr) || (ahr))
321 this->setXYSize (width, height);
322
323 n = 0;
324 if (this->currentLayout & WorkSpaceComponent::Vertical) {
325 XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
326 XtSetArg (wargs[n], XmNrightOffset, HiLites); n++;
327 XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_NONE); n++;
328 } else {
329 XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_NONE); n++;
330 XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
331 XtSetArg (wargs[n], XmNbottomOffset, HiLites); n++;
332 }
333 XtSetArg(wargs[n], XmNtopOffset, HiLites); n++;
334 XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
335 XtSetArg(wargs[n], XmNleftOffset, HiLites); n++;
336 XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
337 XtSetArg(wargs[n], XmNalignment, XmALIGNMENT_CENTER); n++;
338 XtSetArg(wargs[n], XmNuserData, this); n++;
339 this->label = XmCreateLabel(standInRoot, "interactor_label", wargs, n);
340 XtManageChild (this->label);
341 this->passEvents (this->label, TRUE);
342
343 const char *new_label = this->interactorInstance->getInteractorLabel();
344 if ((new_label) && (new_label[0]))
345 this->WorkSpaceComponent::SetLabelResource(this->label, new_label);
346
347 if (this->currentLayout & WorkSpaceComponent::Vertical) {
348 XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
349 XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_FORM); n++;
350 XtSetArg (wargs[n], XmNtopWidget, this->label); n++;
351 XtSetArg (wargs[n], XmNleftOffset, HiLites); n++;
352 } else {
353 XtSetArg (wargs[n], XmNtopOffset, HiLites); n++;
354 XtSetArg (wargs[n], XmNtopAttachment, XmATTACH_FORM); n++;
355 XtSetArg (wargs[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
356 XtSetArg (wargs[n], XmNleftWidget, this->label); n++;
357 }
358 XtSetArg (wargs[n], XmNbottomAttachment, XmATTACH_FORM); n++;
359 XtSetArg (wargs[n], XmNbottomOffset, HiLites); n++;
360 XtSetArg (wargs[n], XmNrightAttachment, XmATTACH_FORM); n++;
361 XtSetArg (wargs[n], XmNrightOffset, HiLites); n++;
362 XtSetArg (wargs[n], XmNuserData, this); n++;
363 this->customPart = XmCreateForm(standInRoot, "interactive_form", wargs, n);
364 XtManageChild(this->customPart);
365 this->createInteractivePart(this->customPart);
366
367 this->passEvents (this->customPart, FALSE);
368
369 //
370 // Set the label after creating the interactive part in case the
371 // sub-class wants to override setLabel().
372 //
373 labelString = ii->getInteractorLabel();
374 ASSERT(labelString);
375 this->setLabel(labelString, FALSE);
376
377 // Set to ! because must be sure the function does something.
378 this->currentLayout|= WorkSpaceComponent::NotSet;
379 this->layoutInteractor();
380
381 //
382 // Register selection callback.
383 //
384 XmWorkspaceAddCallback (this->getRootWidget(), XmNselectionCallback,
385 (XtCallbackProc)Component_SelectWorkSpaceComponentCB, (void *)this);
386
387 //
388 // Make sure the interactive part contains the correct initial value.
389 //
390 this->updateDisplayedInteractorValue();
391
392 this->setAppearance (this->developerStyle);
393
394 this->installResizeHandler();
395
396 //
397 // Perform any actions that need to be done after the parent is managed.
398 //
399 this->completeInteractivePart();
400
401 if ((avr)||(ahr))
402 this->setUserDimensions (width, height);
403 }
404
405 //
406 // Pass button and motion events through to the parent of w.
407 //
passEvents(Widget w,boolean dnd)408 void Interactor::passEvents(Widget w, boolean dnd)
409 {
410 this->WorkSpaceComponent::passEvents (w, dnd);
411 if (dnd) this->setDragWidget(w);
412 }
413
414
415 //
416 // O R I E N T A T I O N O R I E N T A T I O N O R I E N T A T I O N
417 // O R I E N T A T I O N O R I E N T A T I O N O R I E N T A T I O N
418 // O R I E N T A T I O N O R I E N T A T I O N O R I E N T A T I O N
419 // O R I E N T A T I O N O R I E N T A T I O N O R I E N T A T I O N
420 //
421 // It's no longer necessary to do arithmetic inside the Interactor.
422 // The original XmBulletinBoard implementation is replaced with an XmForm.
423 // So things lay themselves out and stay laid out. The only quirky part is
424 // is the XmLabel widget which must be forced to the proper size the first
425 // time it appears on the screen. When changing the layout simply change
426 // form attachments.
427 //
setBlankLabelLayout(boolean blank_label)428 void Interactor::setBlankLabelLayout(boolean blank_label)
429 {
430 if ((this->currentLayout & WorkSpaceComponent::NotSet) == 0) {
431 if ((blank_label)&&
432 ((this->currentLayout & WorkSpaceComponent::BlankLabel)!=0)) return ;
433 if ((!blank_label)&&
434 ((this->currentLayout & WorkSpaceComponent::BlankLabel)==0)) return ;
435 } else {
436 if (blank_label) this->currentLayout|= WorkSpaceComponent::BlankLabel;
437 else this->currentLayout&= ~WorkSpaceComponent::BlankLabel;
438 return ;
439 }
440
441 InteractorInstance *ii = this->interactorInstance;
442 if (blank_label) {
443 ii->setVerticalLayout(TRUE);
444 this->currentLayout|= WorkSpaceComponent::BlankLabel;
445 this->layoutInteractor();
446 } else {
447 this->currentLayout&= ~WorkSpaceComponent::BlankLabel;
448 this->currentLayout|= WorkSpaceComponent::NotSet;
449 this->layoutInteractor();
450 }
451 }
setVerticalLayout(boolean vertical)452 void Interactor::setVerticalLayout(boolean vertical)
453 {
454 if ((this->currentLayout & WorkSpaceComponent::NotSet) == 0) {
455 if ((vertical)&&(this->currentLayout & WorkSpaceComponent::Vertical)) return ;
456 if ((!vertical)&&(this->currentLayout & WorkSpaceComponent::Horizontal)) return ;
457 }
458
459 this->WorkSpaceComponent::setVerticalLayout(vertical);
460 this->layoutInteractor();
461 }
462
layoutInteractor()463 void Interactor::layoutInteractor()
464 {
465 this->resetUserDimensions();
466
467 if (this->currentLayout & WorkSpaceComponent::BlankLabel)
468 this->layoutInteractorWithNoLabel();
469 else if (this->currentLayout & WorkSpaceComponent::Vertical)
470 this->layoutInteractorVertically();
471 else if (this->currentLayout & WorkSpaceComponent::Horizontal)
472 this->layoutInteractorHorizontally();
473 else
474 ASSERT(0);
475 this->currentLayout&= ~WorkSpaceComponent::NotSet;
476 }
477
478
479 //
480 // WRT layoutInteractorHorizontally() and Vertically()...
481 // the order in which you make calls to set form constraints is important.
482 // If you change the order to can wind up with either error message to stderr,
483 // or a mess inside an interactor. Be especially careful with margins.
484 //
485
layoutInteractorHorizontally()486 void Interactor::layoutInteractorHorizontally()
487 {
488 boolean label_managed = XtIsManaged(this->label);
489
490 if (!label_managed) XtManageChild (this->label);
491
492 //
493 // disconnect
494 //
495 XtVaSetValues (this->customPart,
496 XmNtopAttachment, XmATTACH_NONE,
497 NULL);
498 XtVaSetValues (this->label,
499 XmNrightAttachment, XmATTACH_NONE,
500 NULL);
501
502 //
503 // reconnect
504 //
505 XtVaSetValues (this->customPart,
506 XmNtopAttachment, XmATTACH_FORM,
507 XmNleftAttachment, XmATTACH_WIDGET,
508 XmNleftWidget, this->label,
509 XmNtopOffset, HiLites,
510 XmNleftOffset, 0,
511 NULL);
512 XtVaSetValues (this->label,
513 XmNbottomAttachment, XmATTACH_FORM,
514 XmNbottomOffset, HiLites,
515 XmNleftOffset, HiLites,
516 XmNtopOffset, HiLites,
517 NULL);
518 }
519
layoutInteractorVertically()520 void Interactor::layoutInteractorVertically()
521 {
522 boolean label_managed = XtIsManaged(this->label);
523
524 if (!label_managed) {
525 XtManageChild (this->label);
526 }
527
528 //
529 // disconnect
530 //
531 XtVaSetValues (this->label,
532 XmNbottomAttachment, XmATTACH_NONE,
533 XmNbottomOffset, 0,
534 NULL);
535 XtVaSetValues (this->customPart,
536 XmNleftAttachment, XmATTACH_NONE,
537 XmNleftOffset, HiLites,
538 XmNtopAttachment, XmATTACH_NONE,
539 NULL);
540
541 //
542 // reconnect
543 //
544 XtVaSetValues (this->label,
545 XmNrightAttachment, XmATTACH_FORM,
546 XmNrightOffset, HiLites,
547 NULL);
548 XtVaSetValues (this->customPart,
549 XmNtopAttachment, XmATTACH_WIDGET,
550 XmNtopWidget, this->label,
551 XmNtopOffset, 0,
552 XmNleftAttachment, XmATTACH_FORM,
553 NULL);
554 }
555
layoutInteractorWithNoLabel()556 void Interactor::layoutInteractorWithNoLabel()
557 {
558 //
559 // disconnect
560 //
561 XtVaSetValues (this->customPart,
562 XmNtopAttachment, XmATTACH_NONE,
563 NULL);
564 if (XtIsManaged(this->label)) {
565 XtUnmanageChild (this->label);
566 XtVaSetValues (this->getRootWidget(), XmNheight, 0, NULL);
567 }
568
569 //
570 // reconnect
571 //
572 XtVaSetValues (this->customPart,
573 XmNleftAttachment, XmATTACH_FORM, XmNleftOffset, HiLites,
574 XmNtopAttachment, XmATTACH_FORM, XmNtopOffset, HiLites,
575 NULL);
576 }
577
578 // D R A G - N - D R O P --- R E L A T E D S T U F F --- D R A G - N - D R O P
579 // D R A G - N - D R O P --- R E L A T E D S T U F F --- D R A G - N - D R O P
580 // D R A G - N - D R O P --- R E L A T E D S T U F F --- D R A G - N - D R O P
581 // D R A G - N - D R O P --- R E L A T E D S T U F F --- D R A G - N - D R O P
582 //
583 // ...requires only that it be selected
584 //
decideToDrag(XEvent * xev)585 int Interactor::decideToDrag(XEvent *xev)
586 {
587 InteractorInstance *ii = this->interactorInstance;
588 if (!this->developerStyle) return DragSource::Abort;
589 if (!ii->selected) return DragSource::Inactive;
590
591 Display *d = XtDisplay(this->getRootWidget());
592 Atom xoff = XInternAtom (d, DXXOFFSET, False);
593 Atom yoff = XInternAtom (d, DXYOFFSET, False);
594 Screen *screen = XtScreen(this->getRootWidget());
595 Window root = RootWindowOfScreen(screen);
596 int x = 0;
597 int y = 0;
598 ii->getXYPosition (&x, &y);
599 int minx = x;
600 int miny = y;
601 int junk;
602
603 this->workSpace->getSelectedBoundingBox (&minx, &miny, &junk, &junk);
604
605 int xoffset = x - minx;
606 int yoffset = y - miny;
607
608 if (xev->type == ButtonPress) {
609 xoffset+= xev->xbutton.x;
610 yoffset+= xev->xbutton.y;
611 }
612
613 XChangeProperty (d, root, xoff, XA_INTEGER, 32, PropModeReplace,
614 (unsigned char*)&xoffset, 1);
615 XChangeProperty (d, root, yoff, XA_INTEGER, 32, PropModeReplace,
616 (unsigned char*)&yoffset, 1);
617
618 return DragSource::Proceed;
619 }
620
621 //
622 // The header (which will not end up being part of the files) says
623 // "hostname:pid, net length = %d, cfg length = %d\n"
624 //
createNetFiles(Network * netw,FILE * netf,char * cfgfile)625 boolean Interactor::createNetFiles(Network *netw, FILE *netf, char *cfgfile)
626 {
627 netw->setCPSelectionOwner(this->getControlPanel());
628 return (boolean)this->DXDragSource::createNetFiles (netw, netf, cfgfile);
629 }
630
631 //
632 // if the operation was a move and not a copy, then delete
633 // the original interactors.
634 //
dropFinish(long operation,int tag,unsigned char status)635 void Interactor::dropFinish (long operation, int tag, unsigned char status)
636 {
637 //
638 // Delete the atoms set up when starting the drag
639 //
640 Display *d = XtDisplay(this->getRootWidget());
641 Atom xoff_atom = XInternAtom (d, DXXOFFSET, True);
642 Atom yoff_atom = XInternAtom (d, DXYOFFSET, True);
643 Screen *screen = XtScreen(this->getRootWidget());
644 Window root = RootWindowOfScreen(screen);
645 if (xoff_atom != None)
646 XDeleteProperty (d, root, xoff_atom);
647 if (yoff_atom != None)
648 XDeleteProperty (d, root, yoff_atom);
649
650
651 // If the operation was a copy and the type was Trash,
652 // then treat it would be better to treat it like a move
653 // so that the user isn't required to use the Shift key.
654
655 if (status) {
656 if ((operation == XmDROP_MOVE) || (tag == Interactor::Trash)) {
657 //this->getControlPanel()->deleteSelectedInteractors();
658 XtAppContext apcxt = theApplication->getApplicationContext();
659 this->drag_drop_wpid = XtAppAddWorkProc (apcxt, Interactor_DragDropWP,
660 (XtPointer)this);
661 }
662 }
663 }
664
decodeDragType(int tag,char * a,XtPointer * value,unsigned long * length,long operation)665 boolean Interactor::decodeDragType (int tag,
666 char * a, XtPointer *value, unsigned long *length, long operation)
667 {
668 boolean retVal;
669
670 switch (tag) {
671 case Interactor::Modules:
672 // this-convert() comes from DXDragSource and can't be overridden.
673 retVal = this->convert (this->getNetwork(), a, value, length, operation);
674 break;
675
676 // Don't do anything... Just say OK. this->dropFinish does the delete
677 case Interactor::Trash:
678 retVal = TRUE;
679
680 // dummy pointer
681 *value = (XtPointer)malloc(4);
682 *length = 4;
683 break;
684
685 default:
686 retVal = FALSE;
687 break;
688 }
689 return retVal;
690 }
691
692
693 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
694 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
695 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
696 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
697 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
698 // U T I L S U T I L S U T I L S U T I L S U T I L S U T I L S
isA(Symbol classname)699 boolean Interactor::isA(Symbol classname)
700 {
701 Symbol s = theSymbolManager->registerSymbol(ClassInteractor);
702 if (s == classname) return TRUE;
703 return this->WorkSpaceComponent::isA(classname);
704 }
705
706 //
707 // Indicate that the interactor is selected.
708 //
indicateSelect(boolean selected)709 void Interactor::indicateSelect(boolean selected)
710 {
711 if (this->getRootWidget()) {
712 XtVaSetValues(this->getRootWidget(),
713 XmNselected, (selected ? True : False),
714 NULL);
715 }
716 }
717
getComponentHelpTopic()718 const char *Interactor::getComponentHelpTopic()
719 {
720 static char topic[100];
721 sprintf(topic, "%sInteractor",
722 this->getNode()->getNameString());
723 return topic;
724 }
725
GetUserData(Widget widget)726 void *GetUserData(Widget widget)
727 {
728 XtPointer data;
729 ASSERT(widget);
730 XtVaGetValues(widget, XmNuserData, &data, NULL);
731 return (data);
732 }
733
getNetwork()734 Network *Interactor::getNetwork()
735 {
736 ASSERT(this->interactorInstance);
737 return this->interactorInstance->getNetwork();
738 }
getNode()739 Node *Interactor::getNode()
740 {
741 ASSERT(this->interactorInstance);
742 return this->interactorInstance->getNode();
743 }
getControlPanel()744 ControlPanel *Interactor::getControlPanel()
745 {
746 ASSERT(this->interactorInstance);
747 return this->interactorInstance->getControlPanel();
748 }
749
Interactor_DragDropWP(XtPointer clientData)750 extern "C" Boolean Interactor_DragDropWP(XtPointer clientData)
751 {
752 Interactor* ntr = (Interactor*)clientData;
753 ntr->drag_drop_wpid = 0;
754 ntr->getControlPanel()->deleteSelectedInteractors();
755 return TRUE;
756 }
757