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