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 #include <Xm/RowColumn.h>
15 #include <Xm/Form.h>
16 #include <Xm/ScrolledW.h>
17 #include <Xm/PushB.h>
18 #include <Xm/DrawingA.h>
19 #include <Xm/Label.h>
20 #include <Xm/Separator.h>
21
22 //
23 // Is it a good idea to provide a button which will sort up/down the ticks
24 // according to the tick value? Pro: The user doesn't have the ability to
25 // move individual entries around in the list and the AutoAxes module seems
26 // to care about sorted order. Con: The module should be able to deal with
27 // the entries in any order, sort them if it wants to, and echo them back in
28 // sorted order. The ui should just respond to that and not get cluttered up
29 // with sorting code.
30 //
31 // If you use the SORT_TICKS code, then touch TickLabelList.h so that Makefile
32 // does the right thing.
33 //
34 //#define UI_SHOULD_SORT_TICKS 1
35
36 #include "TickLabelList.h"
37 #include "TickLabel.h"
38 #include "ListIterator.h"
39 #include "DXStrings.h"
40 #include "DXApplication.h"
41
42
43 //
44 //
45 String TickLabelList::DefaultResources[] = {
46 "*tllMenuB.width: 20",
47 "*tllMenuB.labelString: ...",
48 "*tllMenuB.recomputeSize: False",
49
50 "*listRC.marginWidth: 1",
51 "*listRC.marginHeight: 1",
52 "*listRC.spacing: 0",
53
54 "*newTop.labelString: Insert at top",
55 "*deleteAll.labelString: Delete all items",
56 "*aasBut.labelString: Append after selection",
57 "*iasBut.labelString: Insert above selection",
58 "*dsBut.labelString: Delete Selection",
59 "*suBut.labelString: Sort in Ascending Order",
60 "*sdBut.labelString: Sort in Descending Order",
61 NULL
62 };
63
64 boolean TickLabelList::SortUp = TRUE;
65
66 boolean TickLabelList::ClassInitialized = FALSE;
67
68 #define DIRTY_APPEND 1
69 #define DIRTY_DELETE 2
70
TickLabelList(const char * header,TickListModifyCB tlmcb,void * clientData)71 TickLabelList::TickLabelList (const char *header, TickListModifyCB tlmcb,
72 void *clientData): UIComponent ("tickList")
73 {
74 this->header = DuplicateString(header);
75 this->dirty = 0;
76
77 this->header_label = this->header_button = this->listRC = NULL;
78 this->popupMenu = NULL;
79
80 this->oldDvals = NULL;
81 this->oldString = NULL;
82
83 this->highest_set_number = 0;
84
85 this->tlmcb = tlmcb;
86 this->clientData = clientData;
87 }
88
initialize()89 void TickLabelList::initialize()
90 {
91 //
92 // Initialize default resources (once only).
93 //
94 if (NOT TickLabelList::ClassInitialized) {
95 this->setDefaultResources(theApplication->getRootWidget(),
96 TickLabelList::DefaultResources);
97 TickLabelList::ClassInitialized = TRUE;
98 }
99 }
100
~TickLabelList()101 TickLabelList::~TickLabelList()
102 {
103 if (this->header) delete this->header;
104
105 ListIterator it(this->ticks);
106 TickLabel *tl;
107
108 while ( (tl = (TickLabel*)it.getNext()) )
109 delete tl;
110 this->ticks.clear();
111
112 if (this->oldDvals) delete this->oldDvals;
113
114 if (this->oldString)
115 delete this->oldString;
116 }
117
118
119 void
createList(Widget parent)120 TickLabelList::createList (Widget parent)
121 {
122 int n;
123 Arg args[25];
124
125 this->initialize();
126
127 Widget form = XtVaCreateWidget (this->name,
128 xmFormWidgetClass, parent,
129 XmNshadowThickness, 2,
130 XmNshadowType, XmSHADOW_ETCHED_IN,
131 NULL);
132
133 n = 0;
134 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
135 XtSetArg (args[n], XmNtopOffset, 50); n++;
136 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
137 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
138 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
139 XtSetArg (args[n], XmNleftOffset, 2); n++;
140 XtSetArg (args[n], XmNrightOffset, 2); n++;
141 XtSetArg (args[n], XmNbottomOffset, 2); n++;
142 XtSetArg (args[n], XmNheight, 150); n++;
143 XtSetArg (args[n], XmNshadowThickness, 0); n++;
144 XtSetArg (args[n], XmNspacing, 0); n++;
145 XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
146 Widget sw = XmCreateScrolledWindow (form, "ticksSW", args, n);
147 XtManageChild (sw);
148 Widget sb = NULL;
149 XtVaGetValues (sw, XmNhorizontalScrollBar, &sb, NULL);
150 if (sb) XtUnmanageChild (sb);
151
152 n = 0;
153 XtSetArg (args[n], XmNresizeWidth, False); n++;
154 this->listRC = XmCreateRowColumn (sw, "listRC", args, n);
155 XtManageChild (this->listRC);
156 XmScrolledWindowSetAreas (sw, NULL, NULL, this->listRC);
157
158 //
159 // Title line...
160 //
161 XmString xmstr = XmStringCreate (this->header, "bold");
162 Widget xlab = XtVaCreateManagedWidget ("listHeader",
163 xmLabelWidgetClass, form,
164 XmNbottomAttachment, XmATTACH_WIDGET,
165 XmNbottomWidget, sw,
166 XmNbottomOffset, 20,
167 XmNleftAttachment, XmATTACH_POSITION,
168 XmNleftPosition, 50,
169 XmNleftOffset, -50,
170 XmNalignment, XmALIGNMENT_CENTER,
171 XmNlabelString, xmstr,
172 NULL);
173 XmStringFree (xmstr);
174
175 //
176 // Labels over the numbers and the text.
177 //
178 xmstr = XmStringCreate ("Tick Location", "small_bold");
179 XtVaCreateManagedWidget ("tickTitle",
180 xmLabelWidgetClass, form,
181 XmNbottomAttachment, XmATTACH_WIDGET,
182 XmNbottomWidget, sw,
183 XmNbottomOffset, 1,
184 XmNleftAttachment, XmATTACH_FORM,
185 XmNleftOffset, 4,
186 XmNlabelString, xmstr,
187 NULL);
188 XmStringFree(xmstr);
189 xmstr = XmStringCreate ("Tick Label", "small_bold");
190 this->labelLabel = XtVaCreateManagedWidget ("textTitle",
191 xmLabelWidgetClass, form,
192 XmNbottomAttachment, XmATTACH_WIDGET,
193 XmNbottomWidget, sw,
194 XmNbottomOffset, 1,
195 XmNrightAttachment, XmATTACH_FORM,
196 XmNrightOffset, 4,
197 XmNlabelString, xmstr,
198 NULL);
199 XmStringFree(xmstr);
200
201
202 //
203 // button for list ops...
204 //
205 Widget button = XtVaCreateManagedWidget ("tllMenuB",
206 xmPushButtonWidgetClass,form,
207 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
208 XmNbottomWidget, xlab,
209 XmNbottomOffset, 0,
210 XmNleftAttachment, XmATTACH_WIDGET,
211 XmNleftWidget, xlab,
212 XmNleftOffset, 10,
213 NULL);
214 XtUninstallTranslations (button);
215 XtAddEventHandler (button, ButtonPressMask|ButtonReleaseMask, False,
216 (XtEventHandler)TickLabelList_ButtonEH, (XtPointer)this);
217
218 n = 0;
219 XtSetArg (args[0], XmNmenuPost, "Shift<Btn4Down>");
220 this->popupMenu = XmCreatePopupMenu(form, "tllPopup", args, 1);
221
222 button = this->ntiButton = XtVaCreateManagedWidget ("newTop",
223 xmPushButtonWidgetClass, this->popupMenu,
224 XmNuserData, 0,
225 NULL);
226 XtAddCallback (button, XmNactivateCallback,
227 (XtCallbackProc)TickLabelList_AppendCB, (XtPointer)this);
228
229 button = this->daButton = XtVaCreateManagedWidget ("deleteAll",
230 xmPushButtonWidgetClass, this->popupMenu,
231 NULL);
232 XtAddCallback (button, XmNactivateCallback,
233 (XtCallbackProc)TickLabelList_DeleteAllCB, (XtPointer)this);
234
235 XtVaCreateManagedWidget ("sep", xmSeparatorWidgetClass, this->popupMenu, NULL);
236
237 button = this->iasButton = XtVaCreateManagedWidget ("iasBut",
238 xmPushButtonWidgetClass, this->popupMenu,
239 NULL);
240 XtAddCallback (button, XmNactivateCallback,
241 (XtCallbackProc)TickLabelList_InsertAboveSelCB, (XtPointer)this);
242
243 button = this->aasButton = XtVaCreateManagedWidget ("aasBut",
244 xmPushButtonWidgetClass, this->popupMenu,
245 NULL);
246 XtAddCallback (button, XmNactivateCallback,
247 (XtCallbackProc)TickLabelList_AppendAfterSelCB, (XtPointer)this);
248
249 button = this->dsButton = XtVaCreateManagedWidget ("dsBut",
250 xmPushButtonWidgetClass, this->popupMenu,
251 NULL);
252 XtAddCallback (button, XmNactivateCallback,
253 (XtCallbackProc)TickLabelList_DeleteSelCB, (XtPointer)this);
254
255 #if UI_SHOULD_SORT_TICKS
256 XtVaCreateManagedWidget ("sep", xmSeparatorWidgetClass, this->popupMenu, NULL);
257
258 button = this->suButton = XtVaCreateManagedWidget("suBut",
259 xmPushButtonWidgetClass, this->popupMenu,
260 NULL);
261 XtAddCallback (button, XmNactivateCallback,
262 (XtCallbackProc)TickLabelList_SortUpCB, (XtPointer)this);
263
264 button = this->sdButton = XtVaCreateManagedWidget("sdBut",
265 xmPushButtonWidgetClass, this->popupMenu,
266 NULL);
267 XtAddCallback (button, XmNactivateCallback,
268 (XtCallbackProc)TickLabelList_SortDownCB, (XtPointer)this);
269 #endif
270
271 //
272 // Create a dummy drawing area in order to catch resize events. This is
273 // necessary for scrolled windows. Their contents' must be manually stretched
274 // horizontally when the window is resized.
275 //
276 n = 0;
277 XtSetArg (args[n], XmNtopAttachment, XmATTACH_FORM); n++;
278 XtSetArg (args[n], XmNtopOffset, 35); n++;
279 XtSetArg (args[n], XmNleftAttachment, XmATTACH_FORM); n++;
280 XtSetArg (args[n], XmNrightAttachment, XmATTACH_FORM); n++;
281 XtSetArg (args[n], XmNbottomAttachment, XmATTACH_FORM); n++;
282 XtSetArg (args[n], XmNleftOffset, 2); n++;
283 XtSetArg (args[n], XmNrightOffset, 2); n++;
284 XtSetArg (args[n], XmNbottomOffset, 2); n++;
285 XtSetArg (args[n], XmNmappedWhenManaged, False); n++;
286 Widget drawa = XmCreateDrawingArea (form, "junk", args, n);
287 XtManageChild (drawa);
288 XtAddCallback (drawa, XmNresizeCallback,
289 (XtCallbackProc)TickLabelList_ResizeTicksCB, (XtPointer)this);
290
291 this->setRootWidget(form);
292
293 ListIterator it(this->ticks);
294 TickLabel *tl;
295 while ( (tl = (TickLabel*)it.getNext()) )
296 tl->createLine (this->listRC);
297 }
298
299
300 void
createLine(double dval,const char * str,int pos)301 TickLabelList::createLine (double dval, const char *str, int pos)
302 {
303 TickLabel *tl = new TickLabel (dval, str, pos,
304 (TickSelectCB)TickLabelList::SelectCB, (void*)this);
305 ASSERT (pos);
306 ASSERT (pos <= (this->ticks.getSize() + 1));
307 this->ticks.insertElement((void *)tl, pos);
308 this->dirty|= DIRTY_APPEND;
309 if (this->listRC)
310 tl->createLine(this->listRC);
311
312 int newpos = this->ticks.getPosition((void*)tl);
313 ASSERT (newpos == pos);
314 this->highest_set_number = MAX(pos, this->highest_set_number);
315
316 this->resizeCallback();
317 }
318
319 void
SelectCB(TickLabel * tlab,void * clientData)320 TickLabelList::SelectCB (TickLabel* tlab, void* clientData)
321 {
322 ASSERT(tlab);
323 if (!tlab->isSelected()) return ;
324
325 ASSERT(clientData);
326 TickLabelList *tll = (TickLabelList*)clientData;
327
328 ListIterator it(tll->ticks);
329 TickLabel *nextTL;
330 while ( (nextTL = (TickLabel*)it.getNext()) ) {
331 if ((nextTL != tlab) && (nextTL->isSelected())) {
332 nextTL->setSelected (FALSE, FALSE);
333 }
334 }
335
336 if (tll->tlmcb)
337 tll->tlmcb (tll, tll->clientData);
338 }
339
340 boolean
isModified()341 TickLabelList::isModified()
342 {
343 if (this->dirty) return TRUE;
344
345 TickLabel *tl;
346 ListIterator it(this->ticks);
347
348 while ( (tl = (TickLabel*)it.getNext()) )
349 if (tl->isModified()) return TRUE;
350 return FALSE;
351 }
352
353 boolean
isNumberModified()354 TickLabelList::isNumberModified()
355 {
356 if (this->dirty) return TRUE;
357
358 TickLabel *tl;
359 ListIterator it(this->ticks);
360
361 while ( (tl = (TickLabel*)it.getNext()) )
362 if (tl->isNumberModified()) return TRUE;
363 return FALSE;
364 }
365
366 boolean
isTextModified()367 TickLabelList::isTextModified()
368 {
369 if (this->dirty) return TRUE;
370
371 TickLabel *tl;
372 ListIterator it(this->ticks);
373
374 while ( (tl = (TickLabel*)it.getNext()) )
375 if (tl->isTextModified()) return TRUE;
376 return FALSE;
377 }
378
379 //
380 // Caller must not free the memory.
381 //
382 double *
getTickNumbers()383 TickLabelList::getTickNumbers()
384 {
385 if (!this->ticks.getSize()) return NULL;
386
387 if (this->oldDvals) {
388 delete this->oldDvals;
389 this->oldDvals = NULL;
390 }
391
392 ListIterator it(this->ticks);
393 TickLabel *tl;
394 double *dvals = new double[this->ticks.getSize()];
395
396 int i = 0;
397 while ( (tl = (TickLabel*)it.getNext()) )
398 dvals[i++] = tl->getNumber();
399
400 return (this->oldDvals = dvals);
401 }
402
403 //
404 // Caller must not free the memory.
405 //
406 String
getTickTextString()407 TickLabelList::getTickTextString()
408 {
409
410 int size = this->ticks.getSize();
411 if (!size) return NULL;
412
413 if ((!this->isTextModified())&&(this->oldString))
414 return this->oldString;
415
416 if (this->oldString) {
417 delete this->oldString;
418 this->oldString = NULL;
419 }
420
421 boolean is_any_text_set = FALSE;
422 ListIterator it(this->ticks);
423 TickLabel *tl;
424 int len = 0;
425 const char *cp;
426 while ( (tl = (TickLabel*)it.getNext()) ) {
427 cp = tl->getText();
428 if (!cp) continue;
429 len+= strlen(cp);
430 if ((len!=2)&&(len!=0)) is_any_text_set = TRUE;
431 else if ((len == 2) && (strcmp(cp, "\"\""))) is_any_text_set = TRUE;
432 }
433
434 if (!is_any_text_set) {
435 return NULL;
436 }
437
438 int newSize = len+10 + (5*size);
439 char *buf = this->oldString = new char[newSize];
440 strcpy (buf, "{ ");
441 int bufLen = strlen(buf);
442 boolean first_loop = TRUE;
443 boolean add_quotes;
444
445 it.setList(this->ticks);
446 while ( (tl = (TickLabel*)it.getNext()) ) {
447 if (!first_loop) {
448 strcpy (&buf[bufLen], ", "); bufLen+= 2;
449 }
450 cp = tl->getText();
451 len = strlen(cp);
452 add_quotes = TRUE;
453 if ((cp[0] == '"') && (cp[len-1] == '"')) add_quotes = FALSE;
454 if (add_quotes) buf[bufLen++] = '"';
455 strcpy (&buf[bufLen], cp); bufLen+= len;
456 if (add_quotes) buf[bufLen++] = '"';
457
458 first_loop = FALSE;
459 }
460
461 ASSERT (newSize > bufLen);
462 strcpy (&buf[bufLen], " }"); bufLen+= 2;
463 return this->oldString;
464 }
465
466 void
markClean()467 TickLabelList::markClean()
468 {
469 this->dirty = 0;
470 TickLabel *tl;
471 ListIterator it(this->ticks);
472
473 while ( (tl = (TickLabel*)it.getNext()) ) {
474 tl->setText();
475 tl->setNumber();
476 }
477 }
478
479 void
markNumbersClean()480 TickLabelList::markNumbersClean()
481 {
482 TickLabel *tl;
483 ListIterator it(this->ticks);
484
485 while ( (tl = (TickLabel*)it.getNext()) ) {
486 tl->setNumber();
487 }
488 }
489
490 void
markTextClean()491 TickLabelList::markTextClean()
492 {
493 TickLabel *tl;
494 ListIterator it(this->ticks);
495
496 while ( (tl = (TickLabel*)it.getNext()) ) {
497 tl->setText();
498 }
499 }
500
501 void
clear()502 TickLabelList::clear()
503 {
504 ListIterator it(this->ticks);
505 TickLabel *tl;
506 while ( (tl = (TickLabel*)it.getNext()) )
507 delete tl;
508 this->ticks.clear();
509
510 ASSERT (this->ticks.getSize() == 0);
511 this->dirty = 0;
512 }
513
514 void
setNumber(int pos,double dval)515 TickLabelList::setNumber (int pos, double dval)
516 {
517 int size = this->ticks.getSize();
518
519 if (pos > size)
520 this->setListSize (pos);
521
522 TickLabel *tl = (TickLabel*)this->ticks.getElement(pos);
523 ASSERT(tl);
524 tl->setNumber(dval);
525
526 this->highest_set_number = MAX(pos, this->highest_set_number);
527 }
528
529 void
setText(int pos,char * str)530 TickLabelList::setText (int pos, char *str)
531 {
532 int size = this->ticks.getSize();
533
534 if (pos > size)
535 this->setListSize (pos);
536
537 TickLabel *tl = (TickLabel*)this->ticks.getElement(pos);
538 ASSERT(tl);
539 tl->setText(str);
540 }
541
542 void
setListSize(int new_size)543 TickLabelList::setListSize (int new_size)
544 {
545 int i, current_size = this->ticks.getSize();
546 TickLabel *tl;
547
548 if (new_size == current_size) {
549 } else if (new_size > current_size) {
550 for (i=current_size+1; i<=new_size; i++)
551 this->createLine (0.0, "", i);
552 } else {
553 List tmpList;
554 for (i=new_size+1; i<=current_size; i++) {
555 tl = (TickLabel*)this->ticks.getElement(i);
556 ASSERT(tl);
557 tmpList.appendElement((void*)tl);
558 }
559 ListIterator it(tmpList);
560 while ( (tl = (TickLabel*)it.getNext()) ) {
561 this->ticks.removeElement((void*)tl);
562 delete tl;
563 }
564 }
565 }
566
resizeCallback()567 void TickLabelList::resizeCallback ()
568 {
569 Dimension width, height, rch;
570 Widget sw = this->listRC;
571
572 while ((sw) && (XtClass(sw)!=xmScrolledWindowWidgetClass))
573 sw = XtParent(sw);
574
575 XtVaGetValues (sw, XmNwidth, &width, XmNheight, &height, NULL);
576 XtVaGetValues (this->listRC,
577 XmNheight, &rch,
578 NULL);
579
580 boolean scrollbar_in_use;
581 if (rch > height) scrollbar_in_use = TRUE;
582 else scrollbar_in_use = FALSE;
583
584 if (scrollbar_in_use) {
585 XtVaSetValues (this->listRC, XmNwidth, width-20, NULL);
586 XtVaSetValues (this->labelLabel, XmNrightOffset, 26, NULL);
587 } else {
588 XtVaSetValues (this->listRC, XmNwidth, width-2, NULL);
589 XtVaSetValues (this->labelLabel, XmNrightOffset, 8, NULL);
590 }
591 }
592
593 //
594 // Using the list of TickLabel objects, create an array. Sort the array.
595 // Then clear the original list and rebuild it using the contents of the array.
596 //
sortList(boolean up)597 void TickLabelList::sortList (boolean up)
598 {
599 #if UI_SHOULD_SORT_TICKS
600 int size = this->ticks.getSize();
601 TickLabelList::SortUp = up;
602 ASSERT (size > 1);
603 int i;
604 TickLabel **tla = new TickLabel*[size];
605 for (i=1; i<=size; i++)
606 tla[i-1] = (TickLabel*)this->ticks.getElement(i);
607
608 qsort (tla, size, sizeof(TickLabel*), TickLabelList_SortFunc);
609
610 this->ticks.clear();
611
612 XtUnmanageChild (this->listRC);
613 for (i=0; i<size; i++) {
614 this->ticks.appendElement((void*)tla[i]);
615 tla[i]->destroyLine();
616 }
617 for (i=0; i<size; i++) {
618 tla[i]->setPosition(i+1);
619 tla[i]->createLine(this->listRC);
620 }
621 XtManageChild (this->listRC);
622
623 this->dirty|= DIRTY_APPEND;
624
625 delete tla;
626 #endif
627 }
628
629 extern "C" {
630
631 int
TickLabelList_SortFunc(const void * e1,const void * e2)632 TickLabelList_SortFunc (const void* e1, const void* e2)
633 {
634 #if UI_SHOULD_SORT_TICKS
635 TickLabel** tlp1 = (TickLabel**)e1;
636 TickLabel** tlp2 = (TickLabel**)e2;
637 TickLabel* tl1 = *tlp1;
638 TickLabel* tl2 = *tlp2;
639 double dval1 = tl1->getNumber();
640 double dval2 = tl2->getNumber();
641
642 if (TickLabelList::SortUp) {
643 if (dval1 > dval2) return 1;
644 if (dval1 < dval2) return -1;
645 } else {
646 if (dval1 < dval2) return 1;
647 if (dval1 > dval2) return -1;
648 }
649 ASSERT (dval1 == dval2);
650 #endif
651 return 0;
652 }
653
TickLabelList_ButtonEH(Widget,XtPointer clientData,XEvent * e,Boolean *)654 void TickLabelList_ButtonEH(Widget , XtPointer clientData,
655 XEvent *e, Boolean *)
656 {
657 TickLabelList *tlab = (TickLabelList *)clientData;
658 ASSERT(tlab);
659 XmMenuPosition(tlab->popupMenu , (XButtonPressedEvent *)e);
660
661 if (e->type == ButtonRelease) XtManageChild(tlab->popupMenu);
662 else XtAppAddTimeOut (theApplication->getApplicationContext(), 100,
663 (XtTimerCallbackProc)XtManageChild, (XtPointer)tlab->popupMenu);
664
665 //
666 // Enable/Disable certain items based on list selection.
667 //
668 TickLabel *tl;
669 ListIterator it(tlab->ticks);
670 boolean any_selected = FALSE;
671 while ((!any_selected) && (tl = (TickLabel*)it.getNext()))
672 if (tl->isSelected()) any_selected = TRUE;
673 XtSetSensitive (tlab->aasButton, (Boolean)any_selected);
674 XtSetSensitive (tlab->iasButton, (Boolean)any_selected);
675 XtSetSensitive (tlab->dsButton, (Boolean)any_selected);
676
677 XtSetSensitive (tlab->daButton, (Boolean)(tlab->ticks.getSize() != 0));
678
679 #if UI_SHOULD_SORT_TICKS
680 XtSetSensitive (tlab->suButton, (Boolean)(tlab->ticks.getSize() > 1));
681 XtSetSensitive (tlab->sdButton, (Boolean)(tlab->ticks.getSize() > 1));
682 #endif
683 }
684
685
686 //
687 // Horizontally resize the contents of the 3 scrolled windows in TicksLabels.
688 //
TickLabelList_ResizeTicksCB(Widget,XtPointer clientData,XtPointer)689 void TickLabelList_ResizeTicksCB(Widget , XtPointer clientData, XtPointer)
690 {
691 ASSERT(clientData);
692 TickLabelList *tll = (TickLabelList *)clientData;
693 tll->resizeCallback();
694 }
695
TickLabelList_DeleteAllCB(Widget,XtPointer clientData,XtPointer)696 void TickLabelList_DeleteAllCB(Widget , XtPointer clientData, XtPointer)
697 {
698 ASSERT(clientData);
699 TickLabelList *tll = (TickLabelList *)clientData;
700
701
702 tll->clear();
703 tll->dirty|= DIRTY_DELETE;
704
705 tll->highest_set_number = 0;
706
707 tll->resizeCallback();
708 if (tll->tlmcb)
709 tll->tlmcb (tll, tll->clientData);
710 }
711
TickLabelList_AppendCB(Widget w,XtPointer clientData,XtPointer)712 void TickLabelList_AppendCB(Widget w, XtPointer clientData, XtPointer)
713 {
714 ASSERT(clientData);
715 TickLabelList *tll = (TickLabelList *)clientData;
716
717 //
718 // Inovke the callback only if adding the first iterm.
719 //
720 boolean call_callback = FALSE;
721 int size = tll->ticks.getSize();
722 if (size == 0) call_callback = TRUE;
723
724 int newTail;
725 XtVaGetValues (w, XmNuserData, &newTail, NULL);
726
727 int newPos;
728 if (newTail)
729 newPos = 1 + size;
730 else
731 newPos = 1;
732
733 tll->createLine (0.0, "", newPos);
734 if ((tll->tlmcb) && (call_callback))
735 tll->tlmcb (tll, tll->clientData);
736 }
737
TickLabelList_AppendAfterSelCB(Widget,XtPointer clientData,XtPointer)738 void TickLabelList_AppendAfterSelCB(Widget , XtPointer clientData, XtPointer)
739 {
740 int newPos;
741
742 ASSERT(clientData);
743 TickLabelList *tll = (TickLabelList *)clientData;
744
745 TickLabel *tl, *sel;
746 ListIterator it(tll->ticks);
747 sel = NULL;
748 newPos = 1;
749 while ( (tl = (TickLabel*)it.getNext()) ) {
750 if (tl->isSelected()) {
751 sel = tl;
752 break;
753 }
754 newPos++;
755 }
756 ASSERT(sel);
757
758 tll->createLine (0.0, "", newPos+1);
759 }
760
TickLabelList_InsertAboveSelCB(Widget,XtPointer clientData,XtPointer)761 void TickLabelList_InsertAboveSelCB(Widget , XtPointer clientData, XtPointer)
762 {
763 int newPos;
764
765 ASSERT(clientData);
766 TickLabelList *tll = (TickLabelList *)clientData;
767
768 TickLabel *tl, *sel;
769 ListIterator it(tll->ticks);
770 sel = NULL;
771 newPos = 1;
772 while ( (tl = (TickLabel*)it.getNext()) ) {
773 if (tl->isSelected()) {
774 sel = tl;
775 break;
776 }
777 newPos++;
778 }
779 ASSERT(sel);
780
781 tll->createLine (0.0, "", newPos);
782 }
783
TickLabelList_DeleteSelCB(Widget,XtPointer clientData,XtPointer)784 void TickLabelList_DeleteSelCB(Widget , XtPointer clientData, XtPointer)
785 {
786 ASSERT(clientData);
787 TickLabelList *tll = (TickLabelList *)clientData;
788
789 TickLabel *tl, *sel;
790 ListIterator it(tll->ticks);
791 sel = NULL;
792 while ( (tl = (TickLabel*)it.getNext()) ) {
793 if (tl->isSelected()) {
794 sel = tl;
795 break;
796 }
797 }
798 ASSERT(sel);
799
800 tll->ticks.removeElement((void*)sel);
801 delete sel;
802
803 tll->resizeCallback();
804 }
805
TickLabelList_SortUpCB(Widget,XtPointer clientData,XtPointer)806 void TickLabelList_SortUpCB(Widget , XtPointer clientData, XtPointer)
807 {
808 ASSERT(clientData);
809 TickLabelList *tll = (TickLabelList *)clientData;
810 tll->sortList(TRUE);
811 }
812
TickLabelList_SortDownCB(Widget,XtPointer clientData,XtPointer)813 void TickLabelList_SortDownCB(Widget , XtPointer clientData, XtPointer)
814 {
815 ASSERT(clientData);
816 TickLabelList *tll = (TickLabelList *)clientData;
817 tll->sortList(FALSE);
818 }
819
820 } // extern "C"
821