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/Form.h>
17 
18 #include "SliderInteractor.h"
19 #include "SetScalarAttrDialog.h"
20 #include "InteractorStyle.h"
21 
22 #include "ScalarNode.h"
23 
24 #include "ScalarInstance.h"
25 #include "Application.h"
26 #include "ErrorDialogManager.h"
27 #include "../widgets/Slider.h"
28 
29 boolean SliderInteractor::SliderInteractorClassInitialized = FALSE;
30 
31 String SliderInteractor::DefaultResources[] =  {
32     ".allowHorizontalResizing:	True",
33     "*form*horizontalSpacing:	5",
34     "*form*verticalSpacing:	5",
35     "*Offset:			5",
36     "*form.resizable:		False",
37     "*recomputeSize: 		False",
38     "*bboard*shadowThickness:   0",
39     "*slider*topOffset:		2",
40     "*slider*bottomOffset:	2",
41     "*slider*leftOffset:	2",
42     "*slider*rightOffset:	2",
43     "*wwLeftOffset:		0",
44     "*wwTopOffset:		0",
45 
46     "*accelerators:   #augment\n"
47 #if 0
48         "<Btn2Down>,<Btn2Up>:            uicHelpInteractor()",
49 #endif
50         "<Key>Return:                    BulletinBoardReturn()",
51 
52 	NUL(char*)
53 };
54 
55 //
56 // One time class initializations.
57 //
58 
SliderInteractor(const char * name,InteractorInstance * ii)59 SliderInteractor::SliderInteractor(const char *name,
60                       InteractorInstance *ii) : ScalarInteractor(name,ii)
61 {
62     this->componentForm = NULL;
63 }
64 //
65 // One time class initializations.
66 //
initialize()67 void SliderInteractor::initialize()
68 {
69     //
70     // Initialize default resources (once only).
71     //
72     if (NOT SliderInteractor::SliderInteractorClassInitialized)
73     {
74         ASSERT(theApplication);
75         this->setDefaultResources(theApplication->getRootWidget(),
76                                   SliderInteractor::DefaultResources);
77         this->setDefaultResources(theApplication->getRootWidget(),
78                                   Interactor::DefaultResources);
79         SliderInteractor::SliderInteractorClassInitialized = TRUE;
80     }
81 }
82 
83 
84 static Widget CreateSliderComponent(Widget,  boolean, double, double,
85 				     double, double, int,   XtCallbackProc,
86 				     int, void *) ;
87 
88 //
89 // Allocate a slider for the given instance.
90 //
AllocateInteractor(const char * name,InteractorInstance * ii)91 Interactor *SliderInteractor::AllocateInteractor(const char *name,
92 				InteractorInstance *ii)
93 {
94 
95     SliderInteractor *si = new SliderInteractor(name,ii);
96     return (Interactor*)si;
97 }
98 
99 //
100 // Perform anything that needs to be done after the parent of
101 // this->interactivePart has been managed.
102 //
completeInteractivePart()103 void SliderInteractor::completeInteractivePart()
104 {
105     if (this->componentForm)
106 	this->passEvents(this->componentForm, TRUE);
107 }
108 //
109 // Build a slider  for the given instance.
110 //
createInteractivePart(Widget form)111 Widget SliderInteractor::createInteractivePart(Widget form)
112 {
113     ScalarNode	*node;
114     ScalarInstance		*si = (ScalarInstance*)
115 					this->interactorInstance;
116 
117     ASSERT(si);
118 
119     node = (ScalarNode*)si->getNode();
120 
121     ASSERT(form);
122     ASSERT(node);
123 
124 	/*
125 	 * Set up and create the Slider component of this interactor
126 	 */
127     this->sliderWidget = CreateSliderComponent(
128 		    form,
129 		    si->isIntegerTypeComponent(),
130 		    si->getMinimum(1),
131 		    si->getMaximum(1),
132 		    si->getComponentValue(1),
133 		    si->getDelta(1),
134 		    si->getDecimals(1),
135 		    (XtCallbackProc)SliderInteractor_SliderCB,
136 		    1,
137 		    (void *)this);
138 
139     return this->sliderWidget;
140 }
141 
142 //
143 // Build a slider component with the given attributes.
144 //
CreateSliderComponent(Widget parent,boolean isInteger,double min,double max,double value,double delta,int decimalPlaces,XtCallbackProc valueChangedCallback,int comp_index,void * clientData)145 static Widget CreateSliderComponent(Widget  parent,
146 				     boolean isInteger,
147 				     double  min,
148 				     double  max,
149 				     double  value,
150 				     double  delta,
151 				     int     decimalPlaces,
152 				     XtCallbackProc valueChangedCallback,
153 				     int     comp_index,
154 				     void * clientData)
155 
156 {
157     Widget widget;
158     int    n;
159     Arg    wargs[30];
160 
161     ASSERT(parent);
162     ASSERT(valueChangedCallback);
163 
164     n = 0;
165     if(isInteger)
166     {
167     	XtSetArg(wargs[n], XmNdataType,	INTEGER); n++;
168     	XtSetArg(wargs[n], XmNdecimalPlaces, 0);  n++;
169     }
170     else
171     {
172     	XtSetArg(wargs[n], XmNdataType,	    DOUBLE);          n++;
173     	XtSetArg(wargs[n], XmNdecimalPlaces, decimalPlaces);  n++;
174     }
175 
176     DoubleSetArg(wargs[n], XmNcurrent,      value);         n++;
177     DoubleSetArg(wargs[n], XmNminimum,      min);           n++;
178     DoubleSetArg(wargs[n], XmNmaximum,      max);           n++;
179     DoubleSetArg(wargs[n], XmNincrement,    delta);         n++;
180     XtSetArg(wargs[n], XmNuserData,         comp_index);     n++;
181     XtSetArg(wargs[n], XmNnoResize,         False);   	     n++;
182     XtSetArg(wargs[n], XmNtopAttachment,    XmATTACH_FORM);  n++;
183     XtSetArg(wargs[n], XmNbottomAttachment, XmATTACH_FORM);  n++;
184     XtSetArg(wargs[n], XmNleftAttachment,   XmATTACH_FORM);  n++;
185     XtSetArg(wargs[n], XmNrightAttachment,  XmATTACH_FORM);  n++;
186 
187     widget = XmCreateSlider(parent, "slider", wargs, n);
188 
189     XtManageChild(widget);
190 
191     XtAddCallback(widget,
192 		  XmNvalueCallback,
193 		  valueChangedCallback,
194 		  clientData);
195 
196     XmSliderAddWarningCallback(widget, (XtCallbackProc)ScalarInteractor_NumberWarningCB,
197 						(XtPointer)clientData);
198     return widget;
199 }
200 
201 //
202 // Call the virtual callback for a change in value.
203 //
SliderInteractor_SliderCB(Widget widget,XtPointer clientData,XtPointer callData)204 extern "C" void SliderInteractor_SliderCB(Widget                  widget,
205 	       XtPointer		clientData,
206  	       XtPointer		callData)
207 {
208     SliderInteractor *si = (SliderInteractor*)clientData;
209     int            component;
210 
211     ASSERT(widget);
212 
213     component = (int)(long)GetUserData(widget);
214     ASSERT(component > 0);
215     si->sliderCallback(widget, component, callData);
216 }
217 
218 //
219 // Accepts value changes and reflects them into other interactors, cdbs
220 // and off course the interactor node output.
221 //
sliderCallback(Widget widget,int component,XtPointer callData)222 void SliderInteractor::sliderCallback(Widget                  widget,
223 		int	component,
224 	        XtPointer	callData)
225 {
226     XmSliderCallbackStruct *cb = (XmSliderCallbackStruct*)callData;
227     ScalarInstance *si = (ScalarInstance*)this->interactorInstance;
228 
229     ASSERT(callData);
230     ASSERT(si);
231 
232     /*
233      * Wait for relevant value (i.e. the button has been released or
234      * there is continuous update), then get the interactor value, store it,
235      * and send it.
236      */
237     boolean send = (cb->reason != XmCR_DRAG) || si->isContinuous();
238     if (send) {
239         double value = cb->value;
240         ScalarNode *node       = (ScalarNode*)si->getNode();
241 	si->setComponentValue(component, value);
242 	char *s = si->buildValueFromComponents();
243 	node->setOutputValue(1,s,DXType::UndefinedType, TRUE);
244 	delete s;
245     }
246 }
247 
248 //
249 // Update the displayed values for this interactor.
250 //
updateDisplayedInteractorValue()251 void SliderInteractor::updateDisplayedInteractorValue()
252 {
253     this->updateSliderValue();
254 }
255 //
256 // Update the displayed values for the slider(s).
257 //
updateSliderValue()258 void SliderInteractor::updateSliderValue()
259 {
260     Arg		   wargs[10];
261     int		   i,components,n=0;
262     // FIXME: should check to make sure we have the correct class of node.
263     ScalarInstance *si = (ScalarInstance*)this->interactorInstance;
264     ASSERT(si);
265 
266     /*
267      * For all components.
268      */
269     components = si->getComponentCount();
270 
271     for (i=1 ; i<=components; i++) {
272 	double value = si->getComponentValue(i);
273 
274 	DoubleSetArg(wargs[n], XmNcurrent, value); n++;
275 	XtSetValues(this->sliderWidget, wargs, n);
276     }
277 
278 }
279 
280 //
281 // Make sure the attributes match the resources for the widgets.
282 //
handleInteractivePartStateChange(InteractorInstance * src_ii,boolean major_change)283 void SliderInteractor::handleInteractivePartStateChange(
284 					InteractorInstance *src_ii,
285 					boolean major_change)
286 {
287     Arg		   wargs[8];
288     int		   i,components,n;
289     // FIXME: should check to make sure we have the correct class of node.
290     ScalarInstance *si = (ScalarInstance*)this->interactorInstance;
291 
292     /*
293      * For all components.
294      */
295     components = si->getComponentCount();
296 
297     for (i=1 ; i<=components; i++) {
298 
299 	int decimals = si->getDecimals(i);
300 	double delta = si->getDelta(i);
301 	double max   = si->getMaximum(i);
302 	double min   = si->getMinimum(i);
303 
304 	/*
305 	 * Update the Slider.
306 	 */
307 	n = 0;
308         if (NOT si->isIntegerTypeComponent())
309 	{
310 	    XtSetArg(wargs[n], XmNdecimalPlaces, decimals); n++;
311 	}
312 
313 	DoubleSetArg(wargs[n], XmNmaximum, max); 		n++;
314 	DoubleSetArg(wargs[n], XmNminimum, min); 		n++;
315 	DoubleSetArg(wargs[n], XmNincrement,    delta);   n++;
316 
317 	XtSetValues(this->sliderWidget, wargs, n);
318     }
319 
320     this->updateSliderValue();
321 }
322 
323