1 /**************************************************************************\
2  *
3  *  This file is part of the Coin 3D visualization library.
4  *  Copyright (C) by Kongsberg Oil & Gas Technologies.
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU General Public License
8  *  ("GPL") version 2 as published by the Free Software Foundation.
9  *  See the file LICENSE.GPL at the root directory of this source
10  *  distribution for additional information about the GNU GPL.
11  *
12  *  For using Coin with software that can not be combined with the GNU
13  *  GPL, and for taking advantage of the additional benefits of our
14  *  support services, please contact Kongsberg Oil & Gas Technologies
15  *  about acquiring a Coin Professional Edition License.
16  *
17  *  See http://www.coin3d.org/ for more information.
18  *
19  *  Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
20  *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
21  *
22 \**************************************************************************/
23 
24 // ************************************************************************
25 
26 // Class is documented in common/viewers/SoGuiFullViewer.cpp.in.
27 
28 // ************************************************************************
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif // HAVE_CONFIG_H
33 
34 #include <string.h>
35 #include <stdlib.h>
36 #include <math.h>
37 
38 #include <X11/IntrinsicP.h>
39 
40 #include <Xm/Xm.h>
41 #include <Xm/Form.h>
42 #include <Xm/Frame.h>
43 #include <Xm/Label.h>
44 #include <Xm/LabelG.h>
45 #include <Xm/PushB.h>
46 #include <Xm/ToggleB.h>
47 #include <Xm/DialogS.h>
48 #include <Xm/RowColumn.h>
49 #include <Xm/Text.h>
50 #include <Xm/TextF.h>
51 #include <Xm/Scale.h>
52 
53 #include <Inventor/misc/SoBasic.h>
54 #include <Inventor/errors/SoDebugError.h>
55 #include <Inventor/nodes/SoPerspectiveCamera.h>
56 
57 #include <soxtdefs.h>
58 #include <Inventor/Xt/SoXtInternal.h>
59 #include <Inventor/Xt/SoXtBasic.h>
60 #include <Inventor/Xt/SoXt.h>
61 #include <Inventor/Xt/SoXtResource.h>
62 #include <Inventor/Xt/widgets/SoXtThumbWheel.h>
63 #include <Inventor/Xt/widgets/SoXtPopupMenu.h>
64 
65 #include <Inventor/Xt/viewers/SoXtFullViewer.h>
66 #include <Inventor/Xt/viewers/SoXtFullViewerP.h>
67 
68 #if HAVE_LIBXPM
69 #include <X11/xpm.h>
70 #include <Inventor/Xt/common/pixmaps/pick.xpm>
71 #include <Inventor/Xt/common/pixmaps/view.xpm>
72 #include <Inventor/Xt/common/pixmaps/home.xpm>
73 #include <Inventor/Xt/common/pixmaps/set_home.xpm>
74 #include <Inventor/Xt/common/pixmaps/view_all.xpm>
75 #include <Inventor/Xt/common/pixmaps/seek.xpm>
76 #endif // HAVE_LIBXPM
77 
78 // *************************************************************************
79 
80 #define PRIVATE(o) (o->pimpl)
81 #define PUBLIC(o) (o->pub)
82 
83 // *************************************************************************
84 
85 SOXT_OBJECT_ABSTRACT_SOURCE(SoXtFullViewer);
86 
87 // *************************************************************************
88 
89 enum DefaultViewerButtons {
90   INTERACT_BUTTON = 0,
91   EXAMINE_BUTTON,
92   HOME_BUTTON,
93   SET_HOME_BUTTON,
94   VIEW_ALL_BUTTON,
95   SEEK_BUTTON,
96 
97   FIRST_BUTTON = INTERACT_BUTTON,
98   LAST_BUTTON = SEEK_BUTTON
99 };
100 
101 #define VIEWERBUTTON(button) ((Widget) ((*this->viewerButtonWidgets)[button]))
102 
103 // *************************************************************************
104 
105 /*!
106   \var float SoXtFullViewer::leftWheelVal
107 
108   The value of the left thumb wheel.  Do not set directly, use access method.
109 */
110 
111 /*!
112   \var Widget SoXtFullViewer::leftWheel
113 
114   The widget for the left thumb wheel.
115 */
116 
117 /*!
118   \var Widget SoXtFullViewer::leftWheelLabel
119 
120   The widget for the label below the left thumb wheel.
121 */
122 
123 /*!
124   \var char * SoXtFullViewer::leftWheelStr
125 
126   The string used in the label under the left thumb wheel.
127 */
128 
129 /*!
130   \var float SoXtFullViewer::bottomWheelVal
131 
132   The value of the bottom thumb wheel.  Do not set directly, use access method.
133 */
134 
135 /*!
136   \var Widget SoXtFullViewer::bottomWheel
137 
138   The widget for the bottom thumb wheel.
139 */
140 
141 /*!
142   \var Widget SoXtFullViewer::bottomWheelLabel
143 
144   The widget for the label besides the bottom thumb wheel.
145 */
146 
147 /*!
148   \var char * SoXtFullViewer::bottomWheelStr
149 
150   The string used in the label besides the bottom thumb wheel.
151 */
152 
153 /*!
154   \var float SoXtFullViewer::rightWheelVal
155 
156   The value of the right thumb wheel.  Do not set directly, use access method.
157 */
158 
159 /*!
160   \var Widget SoXtFullViewer::rightWheel
161 
162   The widget for the right thumb wheel.
163 */
164 
165 /*!
166   \var Widget SoXtFullViewer::rightWheelLabel
167 
168   The widget for the label below the right thumb wheel.
169 */
170 
171 /*!
172   \var char * SoXtFullViewer::rightWheelStr
173 
174   The string used in the label below the right thumb wheel.
175 */
176 
177 /*!
178   \enum SoXtFullViewer::BuildFlag
179 
180   Flags for building various parts of the viewer.
181 */
182 
183 /*!
184   \var SbPList * SoXtFullViewer::viewerButtonWidgets
185 
186   The list of button widgets for the right viewer decoration.
187 */
188 
189 /*!
190   \var SbBool SoXtFullViewer::popupEnabled
191 
192   Whether the popup menu is enabled or not.
193 */
194 
195 /*!
196   \var SoXtPopupMenu * SoXtFullViewer::prefmenu
197 
198   The popup menu manager object.
199 */
200 
201 /*!
202   \var char * SoXtFullViewer::popupTitle
203 
204   The title for the popup menu,
205 */
206 
207 
208 // *************************************************************************
209 
210 /*!
211   Constructor.
212 */
213 
SoXtFullViewer(Widget parent,const char * name,SbBool embed,BuildFlag flags,Type type,SbBool build)214 SoXtFullViewer::SoXtFullViewer(Widget parent,
215                                const char * name,
216                                SbBool embed,
217                                BuildFlag flags,
218                                Type type,
219                                SbBool build)
220   : inherited(parent, name, embed, type, FALSE),
221     popupTitle(NULL)
222 {
223   PRIVATE(this) = new SoXtFullViewerP(this);
224 
225   // initialization of protected members
226   this->leftWheel = NULL;
227   this->leftWheelStr = strcpy(new char [sizeof("Motion X")+1], "Motion X");
228   this->leftWheelVal = 0.0f;
229   this->leftWheelLabel = NULL;
230 
231   this->bottomWheel = NULL;
232   this->bottomWheelStr = strcpy(new char [sizeof("Motion Y")+1], "Motion Y");
233   this->bottomWheelVal = 0.0f;
234   this->bottomWheelLabel = NULL;
235 
236   this->rightWheel = NULL;
237   this->rightWheelStr = strcpy(new char [sizeof("Motion Z")+1], "Motion Z");
238   this->rightWheelVal = 0.0f;
239   this->rightWheelLabel = NULL;
240 
241   // initialization of private members
242   this->leftDecoration = NULL;
243   this->rightDecoration = NULL;
244   this->bottomDecoration = NULL;
245 
246   PRIVATE(this)->viewerbase = NULL;
247   PRIVATE(this)->canvas = NULL;
248 
249   this->popupEnabled = (flags & SoXtFullViewer::BUILD_POPUP) ? TRUE : FALSE;
250   PRIVATE(this)->decorations = (flags & SoXtFullViewer::BUILD_DECORATION) ? TRUE : FALSE;
251 
252   PRIVATE(this)->appButtonsList = new SbPList;
253   this->viewerButtonWidgets = new SbPList;
254 
255   this->prefmenu = NULL;
256 
257   PRIVATE(this)->pixmaps.pick = 0;
258   PRIVATE(this)->pixmaps.pick_ins = 0;
259   PRIVATE(this)->pixmaps.view = 0;
260   PRIVATE(this)->pixmaps.view_ins = 0;
261   PRIVATE(this)->pixmaps.home = 0;
262   PRIVATE(this)->pixmaps.home_ins = 0;
263   PRIVATE(this)->pixmaps.set_home = 0;
264   PRIVATE(this)->pixmaps.set_home_ins = 0;
265   PRIVATE(this)->pixmaps.view_all = 0;
266   PRIVATE(this)->pixmaps.view_all_ins = 0;
267   PRIVATE(this)->pixmaps.seek = 0;
268   PRIVATE(this)->pixmaps.seek_ins = 0;
269 
270   if (build != FALSE) {
271     this->setClassName("SoXtFullViewer");
272     Widget viewer = this->buildWidget(this->getParentWidget());
273     this->setBaseWidget(viewer);
274     this->fitSize(SbVec2s(500, 300));
275   }
276 }
277 
278 /*!
279   The destructor.
280 */
281 
~SoXtFullViewer()282 SoXtFullViewer::~SoXtFullViewer()
283 {
284   delete PRIVATE(this)->appButtonsList;
285   delete this->viewerButtonWidgets;
286 
287   delete PRIVATE(this);
288 }
289 
290 // *************************************************************************
291 
292 static const int SOXT_VIEWER_MIN_HEIGHT_BASE = 30 + /* 90 */ 122 + 8;
293 static const int SOXT_VIEWER_MIN_WIDTH = 300;
294 
295 /*!
296   This method sets whether the decorations should be shown or not.
297 */
298 
299 void
setDecoration(const SbBool enable)300 SoXtFullViewer::setDecoration(const SbBool enable)
301 {
302   if (!!PRIVATE(this)->decorations && !!enable) { return; }
303 
304   if ( (PRIVATE(this)->decorations != enable) &&
305        (PRIVATE(this)->viewerbase != (Widget) NULL) ) {
306     PRIVATE(this)->showDecorationWidgets(enable);
307   }
308   PRIVATE(this)->decorations = enable;
309 
310   if (this->isTopLevelShell() || XtIsShell(XtParent(this->getBaseWidget()))) {
311     Widget shell = this->getShellWidget();
312     Dimension minwidth = SOXT_VIEWER_MIN_WIDTH;
313     Dimension minheight = SOXT_VIEWER_MIN_HEIGHT_BASE +
314       30 * this->viewerButtonWidgets->getLength();
315     if ( enable ) {
316       Dimension width, height;
317       XtVaGetValues(shell,
318                     XmNwidth, &width,
319                     XmNheight, &height,
320                     NULL);
321       width = SoXtMax(width, minwidth);
322       height = SoXtMax(height, minheight);
323       XtVaSetValues(shell,
324                     XmNminWidth, minwidth,
325                     XmNminHeight, minheight,
326                     XmNwidth, width,
327                     XmNheight, height,
328                     NULL);
329     } else {
330       XtVaSetValues(shell,
331                     XmNminWidth, 0,
332                     XmNminHeight, 0,
333                     NULL);
334     }
335   }
336 }
337 
338 /*!
339   This method returns whether the decorations are shown or not.
340 */
341 
342 SbBool
isDecoration(void) const343 SoXtFullViewer::isDecoration(void) const
344 {
345   return PRIVATE(this)->decorations;
346 }
347 
348 // *************************************************************************
349 
350 /*!
351   This method sets whether the popup menu should be enabled or not.
352 */
353 
354 void
setPopupMenuEnabled(const SbBool enable)355 SoXtFullViewer::setPopupMenuEnabled(const SbBool enable)
356 {
357   this->popupEnabled = enable;
358 }
359 
360 /*!
361   This method returns whether the popup menu is enabled or not.
362 */
363 
364 SbBool
isPopupMenuEnabled(void) const365 SoXtFullViewer::isPopupMenuEnabled(void) const
366 {
367   return this->popupEnabled;
368 }
369 
370 
371 // *************************************************************************
372 
373 /*!
374   Return value is either NULL or a widget of type xmFormWidgetClass (Xm/Form.h)
375 
376   AppPushButtons are on the left decoration.
377 */
378 
379 Widget
getAppPushButtonParent(void) const380 SoXtFullViewer::getAppPushButtonParent(void) const
381 {
382   return PRIVATE(this)->appButtonsForm;
383 }
384 
385 /*!
386   Not implemented.
387 
388   Each button will be set to 30x30 pixels, and they will appear on the left
389   viewer decoration.
390 */
391 
392 void
addAppPushButton(Widget button)393 SoXtFullViewer::addAppPushButton(Widget button)
394 {
395   PRIVATE(this)->resetAppPushButtons();
396   PRIVATE(this)->appButtonsList->append(button);
397   PRIVATE(this)->layoutAppPushButtons();
398 }
399 
400 /*!
401   FIXME: write doc
402 */
403 
404 void
insertAppPushButton(Widget button,int idx)405 SoXtFullViewer::insertAppPushButton(Widget button,
406                                     int idx)
407 {
408   PRIVATE(this)->resetAppPushButtons();
409   PRIVATE(this)->appButtonsList->insert(button, idx);
410   PRIVATE(this)->layoutAppPushButtons();
411 }
412 
413 /*!
414   FIXME: write doc
415 */
416 
417 void
removeAppPushButton(Widget button)418 SoXtFullViewer::removeAppPushButton(Widget button)
419 {
420   int idx = PRIVATE(this)->appButtonsList->find(button);
421   assert(idx != -1 && "tried to remove non-existant button");
422   PRIVATE(this)->resetAppPushButtons();
423   PRIVATE(this)->appButtonsList->remove(idx);
424   PRIVATE(this)->layoutAppPushButtons();
425 }
426 
427 /*!
428   FIXME: write doc
429 */
430 
431 int
findAppPushButton(Widget button) const432 SoXtFullViewer::findAppPushButton(Widget button) const
433 {
434   return PRIVATE(this)->appButtonsList->find(button);
435 }
436 
437 /*!
438   FIXME: write doc
439 */
440 
441 int
lengthAppPushButton(void) const442 SoXtFullViewer::lengthAppPushButton(void) const
443 {
444   return PRIVATE(this)->appButtonsList->getLength();
445 }
446 
447 // *************************************************************************
448 
449 /*!
450   FIXME: write doc
451 */
452 
453 Widget
getRenderAreaWidget(void) const454 SoXtFullViewer::getRenderAreaWidget(void) const
455 {
456   return PRIVATE(this)->canvas;
457 }
458 
459 // *************************************************************************
460 
461 // Documented in superclass.
462 Widget
buildWidget(Widget parent)463 SoXtFullViewer::buildWidget(Widget parent)
464 {
465   int depth = 0;
466   XtVaGetValues(parent, XmNdepth, &depth, NULL);
467 
468   PRIVATE(this)->viewerbase = XtVaCreateManagedWidget(this->getWidgetName(),
469                                                       xmFormWidgetClass, parent,
470                                                       NULL);
471   this->registerWidget(PRIVATE(this)->viewerbase);
472 
473   char * titleString = NULL;
474   SoXtResource rsc(PRIVATE(this)->viewerbase);
475   rsc.getResource("title", XmRString, titleString);
476   if (titleString != NULL)
477     this->setTitle(titleString);
478 
479   PRIVATE(this)->canvas = inherited::buildWidget(PRIVATE(this)->viewerbase);
480   XtVaSetValues(PRIVATE(this)->canvas,
481                 XmNleftAttachment, XmATTACH_FORM,
482                 XmNleftOffset, 30,
483                 XmNtopAttachment, XmATTACH_FORM,
484                 XmNrightAttachment, XmATTACH_FORM,
485                 XmNrightOffset, 30,
486                 XmNbottomAttachment, XmATTACH_FORM,
487                 XmNbottomOffset, 30,
488                 NULL);
489 
490   this->buildDecoration(PRIVATE(this)->viewerbase);
491 
492   if (this->isTopLevelShell() &&
493       PRIVATE(this)->decorations != FALSE) {
494     Widget shell = this->getShellWidget();
495     if (shell != NULL) {
496       Dimension minheight =
497         30 + 122 + 30 * this->viewerButtonWidgets->getLength() + 8;
498       Dimension width, height;
499       XtVaGetValues(shell,
500                     XmNwidth, &width,
501                     XmNheight, &height,
502                     NULL);
503       width = SoXtMax(width, (Dimension) 300);
504       height = SoXtMax(height, minheight);
505       XtVaSetValues(shell,
506                     XmNminWidth, 300,
507                     XmNminHeight, minheight,
508                     XmNwidth, width,
509                     XmNheight, height,
510                     NULL);
511     }
512   }
513   return PRIVATE(this)->viewerbase;
514 }
515 
516 // *************************************************************************
517 
518 /*!
519   FIXME: write doc
520 */
521 
522 void
buildDecoration(Widget parent)523 SoXtFullViewer::buildDecoration(Widget parent)
524 {
525   this->leftDecoration = this->buildLeftTrim(parent);
526   XtVaSetValues(this->leftDecoration,
527                 XmNleftAttachment, XmATTACH_FORM,
528                 XmNtopAttachment, XmATTACH_FORM,
529                 XmNrightAttachment, XmATTACH_OPPOSITE_FORM,
530                 XmNrightOffset, -30,
531                 XmNbottomAttachment, XmATTACH_FORM,
532                 XmNbottomOffset, 30,
533                 NULL);
534 
535   this->rightDecoration = this->buildRightTrim(parent);
536   XtVaSetValues(this->rightDecoration,
537                 XmNleftAttachment, XmATTACH_OPPOSITE_FORM,
538                 XmNleftOffset, -30,
539                 XmNtopAttachment, XmATTACH_FORM,
540                 XmNrightAttachment, XmATTACH_FORM,
541                 XmNbottomAttachment, XmATTACH_FORM,
542                 XmNbottomOffset, 30,
543                 NULL);
544 
545   this->bottomDecoration = this->buildBottomTrim(parent);
546   XtVaSetValues(this->bottomDecoration,
547                 XmNleftAttachment, XmATTACH_FORM,
548                 XmNtopAttachment, XmATTACH_OPPOSITE_FORM,
549                 XmNtopOffset, -30,
550                 XmNrightAttachment, XmATTACH_FORM,
551                 XmNbottomAttachment, XmATTACH_FORM,
552                 NULL);
553 }
554 
555 // *************************************************************************
556 
557 /*!
558   This method creates the left decoration form.
559 
560   Return value is a Motif widget of the xmFormWidgetClass type.
561   The left decoration is 30 pixels wide.
562 */
563 
564 Widget
buildLeftTrim(Widget parent)565 SoXtFullViewer::buildLeftTrim(Widget parent)
566 {
567   Widget trim = XtVaCreateManagedWidget("LeftTrim",
568       xmFormWidgetClass, parent,
569       NULL);
570 
571   // build application buttons
572   PRIVATE(this)->appButtonsForm = PRIVATE(this)->buildAppButtonsForm(trim);
573   XtVaSetValues(PRIVATE(this)->appButtonsForm,
574     XmNleftAttachment, XmATTACH_FORM,
575     XmNtopAttachment, XmATTACH_FORM,
576     XmNrightAttachment, XmATTACH_FORM,
577     NULL);
578 
579   // add left thumb wheel
580   this->leftWheel = XtVaCreateManagedWidget("LeftWheel",
581     soxtThumbWheelWidgetClass, trim,
582     XmNleftAttachment, XmATTACH_FORM,
583     XmNleftOffset, 2,
584     XmNrightAttachment, XmATTACH_FORM,
585     XmNrightOffset, 2,
586     XmNbottomAttachment, XmATTACH_FORM,
587     XmNbottomOffset, 2,
588     XmNheight, 122,
589     XmNorientation, XmVERTICAL,
590     XmNshadowType, XmSHADOW_OUT,
591     XmNhighlightThickness, 0,
592     XmNshadowThickness, 2,
593     XmNtraversalOn, False,
594     NULL);
595 
596   XtAddCallback(this->leftWheel,
597                 XmNarmCallback, SoXtFullViewerP::leftWheelStartCB, this);
598   XtAddCallback(this->leftWheel,
599                 XmNdisarmCallback, SoXtFullViewerP::leftWheelFinishCB, this);
600   XtAddCallback(this->leftWheel,
601                 XmNvalueChangedCallback, SoXtFullViewerP::leftWheelMotionCB, this);
602 
603   return trim;
604 }
605 
606 // *************************************************************************
607 
608 /*!
609   This method creates the right decoration form.
610 
611   Returned value is a Motif widget of the xmFormWidgetClass type.
612   The form is 30 pixels wide.
613 */
614 
615 Widget
buildRightTrim(Widget parent)616 SoXtFullViewer::buildRightTrim(Widget parent)
617 {
618   Widget trim = XtVaCreateManagedWidget("RightTrim",
619     xmFormWidgetClass, parent,
620     NULL);
621 
622   Widget buttons = this->buildViewerButtons(trim);
623 
624   XtVaSetValues(buttons,
625     XmNleftAttachment, XmATTACH_FORM,
626     XmNtopAttachment, XmATTACH_FORM,
627     XmNrightAttachment, XmATTACH_FORM,
628     XmNbottomAttachment, XmATTACH_OPPOSITE_FORM,
629     XmNbottomOffset, 0 - this->viewerButtonWidgets->getLength() * 30,
630     NULL);
631 
632   // add right thumb wheel
633   this->rightWheel = XtVaCreateManagedWidget("RightWheel",
634     soxtThumbWheelWidgetClass, trim,
635     XmNleftAttachment, XmATTACH_FORM,
636     XmNleftOffset, 2,
637     XmNrightAttachment, XmATTACH_FORM,
638     XmNrightOffset, 2,
639     XmNbottomAttachment, XmATTACH_FORM,
640     XmNbottomOffset, 2,
641     XmNheight, 122,
642     XmNorientation, XmVERTICAL,
643     XmNshadowType, XmSHADOW_OUT,
644     XmNhighlightThickness, 0,
645     XmNshadowThickness, 2,
646     XmNtraversalOn, False,
647     NULL);
648 
649   XtAddCallback(this->rightWheel,
650                 XmNarmCallback, SoXtFullViewerP::rightWheelStartCB, this);
651   XtAddCallback(this->rightWheel,
652                 XmNdisarmCallback, SoXtFullViewerP::rightWheelFinishCB, this);
653   XtAddCallback(this->rightWheel,
654                 XmNvalueChangedCallback, SoXtFullViewerP::rightWheelMotionCB, this);
655 
656   return trim;
657 }
658 
659 // *************************************************************************
660 
661 /*!
662   This method created the bottom decoration form.
663 
664   Return value is a Motif widget of the xmFormWidgetClass type.
665   It is 30 pixels high.
666 */
667 
668 Widget
buildBottomTrim(Widget parent)669 SoXtFullViewer::buildBottomTrim(Widget parent)
670 {
671   Widget trim = XtVaCreateManagedWidget("BottomTrim",
672                                         xmFormWidgetClass, parent,
673                                         NULL);
674 
675   this->leftWheelLabel = XtVaCreateManagedWidget("LeftWheelLabel",
676                                                  xmLabelWidgetClass, trim,
677                                                  XmNleftAttachment, XmATTACH_FORM,
678                                                  XmNtopAttachment, XmATTACH_FORM,
679                                                  XmNbottomAttachment, XmATTACH_FORM,
680                                                  XmNleftOffset, 5,
681                                                  XtVaTypedArg,
682                                                  XmNlabelString, XmRString,
683                                                  this->leftWheelStr, strlen(this->leftWheelStr)+1,
684                                                  NULL);
685 
686   this->bottomWheelLabel = XtVaCreateManagedWidget("BottomWheelLabel",
687                                                    xmLabelWidgetClass, trim,
688                                                    XmNleftAttachment, XmATTACH_WIDGET,
689                                                    XmNleftWidget, this->leftWheelLabel,
690                                                    XmNtopAttachment, XmATTACH_FORM,
691                                                    XmNbottomAttachment, XmATTACH_FORM,
692                                                    XmNleftOffset, 5,
693                                                    XtVaTypedArg,
694                                                    XmNlabelString, XmRString,
695                                                    this->bottomWheelStr, strlen(this->bottomWheelStr)+1,
696                                                    NULL);
697 
698   // add bottom thumb wheel
699   this->bottomWheel = XtVaCreateManagedWidget("BottomWheel",
700                                               soxtThumbWheelWidgetClass, trim,
701                                               XmNorientation, XmHORIZONTAL,
702                                               XmNshadowType, XmSHADOW_OUT,
703                                               XmNhighlightThickness, 0,
704                                               XmNshadowThickness, 2,
705                                               XmNtraversalOn, False,
706                                               XmNleftAttachment, XmATTACH_WIDGET,
707                                               XmNleftWidget, this->bottomWheelLabel,
708                                               XmNleftOffset, 2,
709                                               XmNtopAttachment, XmATTACH_FORM,
710                                               XmNtopOffset, 2,
711                                               XmNbottomAttachment, XmATTACH_FORM,
712                                               XmNbottomOffset, 2,
713                                               XmNwidth, 122,
714                                               NULL);
715 
716   XtAddCallback(this->bottomWheel,
717                 XmNarmCallback, SoXtFullViewerP::bottomWheelStartCB, this);
718   XtAddCallback(this->bottomWheel,
719                 XmNdisarmCallback, SoXtFullViewerP::bottomWheelFinishCB, this);
720   XtAddCallback(this->bottomWheel,
721                 XmNvalueChangedCallback, SoXtFullViewerP::bottomWheelMotionCB, this);
722 
723   this->rightWheelLabel = XtVaCreateManagedWidget("RightWheelLabel",
724                                                   xmLabelWidgetClass, trim,
725                                                   XmNleftAttachment, XmATTACH_WIDGET,
726                                                   XmNleftWidget, this->bottomWheel,
727                                                   XmNalignment, XmALIGNMENT_END,
728                                                   XmNtopAttachment, XmATTACH_OPPOSITE_FORM,
729                                                   XmNtopOffset, -30,
730                                                   XmNbottomAttachment, XmATTACH_FORM,
731                                                   XmNrightAttachment, XmATTACH_FORM,
732                                                   XmNrightOffset, 5,
733                                                   XtVaTypedArg,
734                                                   XmNlabelString, XmRString,
735                                                   this->rightWheelStr, strlen(this->rightWheelStr)+1,
736                                                   NULL);
737 
738   return trim;
739 }
740 
741 // *************************************************************************
742 
743 // Documented in superclass.
744 void
setViewing(SbBool enable)745 SoXtFullViewer::setViewing(SbBool enable)
746 {
747   if ((this->isViewing() && enable) || (!this->isViewing() && !enable)) {
748 #if SOXT_DEBUG
749     SoDebugError::postWarning("SoXtFullViewer::setViewing",
750                               "current state already %s", enable ? "TRUE" : "FALSE");
751 #endif // SOXT_DEBUG
752     return;
753   }
754 
755   inherited::setViewing(enable);
756 
757   if (PRIVATE(this)->viewerbuttons.pick != 0) {
758     XtSetSensitive(PRIVATE(this)->viewerbuttons.pick, enable ? True : False);
759     XtVaSetValues(PRIVATE(this)->viewerbuttons.pick,
760                   XmNset, enable ? False : True,
761                   NULL);
762   }
763 
764   if (PRIVATE(this)->viewerbuttons.view != 0) {
765     XtSetSensitive(PRIVATE(this)->viewerbuttons.view, enable ? False : True);
766     XtVaSetValues(PRIVATE(this)->viewerbuttons.view,
767                   XmNset, enable ? True : False,
768                   NULL);
769   }
770 
771   if (PRIVATE(this)->viewerbuttons.seek != 0) {
772     XtSetSensitive(PRIVATE(this)->viewerbuttons.seek, enable ? True : False);
773   }
774 }
775 
776 // *************************************************************************
777 
778 /*!
779   FIXME: write doc
780 */
781 
782 Widget
buildViewerButtons(Widget parent)783 SoXtFullViewer::buildViewerButtons(Widget parent)
784 {
785   Widget buttons = XtVaCreateWidget("ViewerButtons",
786                                     xmRowColumnWidgetClass, parent,
787                                     XmNrowColumnType, XmWORK_AREA,
788                                     XmNpacking, XmPACK_COLUMN,
789                                     XmNnumColumns, 1,
790                                     XmNspacing, 0,
791                                     XmNmarginWidth, 0,
792                                     XmNmarginHeight, 0,
793                                     NULL);
794 
795   this->createViewerButtons(buttons, this->viewerButtonWidgets);
796 
797   XtSetSensitive(PRIVATE(this)->viewerbuttons.pick, this->isViewing() ? True : False);
798   XtVaSetValues(PRIVATE(this)->viewerbuttons.pick,
799                 XmNset, this->isViewing() ? False : True,
800                 NULL);
801 
802   XtSetSensitive(PRIVATE(this)->viewerbuttons.view, this->isViewing() ? False : True);
803   XtVaSetValues(PRIVATE(this)->viewerbuttons.view,
804                 XmNset, this->isViewing() ? True : False,
805                 NULL);
806 
807   const int numbuttons = this->viewerButtonWidgets->getLength();
808   for (int i = 0; i < numbuttons; i++) {
809     Widget button = (Widget) (*this->viewerButtonWidgets)[i];
810     XtVaSetValues(button,
811                   XmNshadowType, XmSHADOW_OUT,
812                   XmNhighlightThickness, 0,
813                   XmNshadowThickness, 2,
814                   XmNtraversalOn, False,
815                   XmNmarginWidth, 0,
816                   XmNmarginHeight, 0,
817                   XmNmarginLeft, 0,
818                   XmNmarginTop, 0,
819                   XmNmarginRight, 0,
820                   XmNmarginBottom, 0,
821                   XmNrecomputeSize, False,
822                   XmNwidth, 28,
823                   XmNheight, 28,
824                   NULL);
825   }
826 
827 /*
828   XtVaSetValues(buttons,
829     XmNwidth, 30,
830     XmNheight, numbuttons * 31,
831     NULL);
832 */
833 
834   XtManageChild(buttons);
835   return buttons;
836 }
837 
838 // *************************************************************************
839 
840 // Documented in common/viewers/SoGuiFullViewer.cpp.in.
841 void
createViewerButtons(Widget parent,SbPList * buttonlist)842 SoXtFullViewer::createViewerButtons(Widget parent,
843                                     SbPList * buttonlist)
844 {
845 #if SOXT_DEBUG && 0
846   SoDebugError::postInfo("SoXtFullViewer::createViewerButtons", "[enter]");
847 #endif // SOXT_DEBUG
848 
849   int viewerbutton;
850   for (viewerbutton = FIRST_BUTTON; viewerbutton <= LAST_BUTTON; viewerbutton++) {
851 
852     XtCallbackProc proc = NULL;
853     char label[2];
854     label[1] = '\0';
855     switch (viewerbutton) {
856     case INTERACT_BUTTON:
857       proc = SoXtFullViewerP::interactbuttonCB;
858       label[0] = 'I';
859       break;
860     case EXAMINE_BUTTON:
861       proc = SoXtFullViewerP::examinebuttonCB;
862       label[0] = 'E';
863       break;
864     case HOME_BUTTON:
865       proc = SoXtFullViewerP::homebuttonCB;
866       label[0] = 'H';
867       break;
868     case SET_HOME_BUTTON:
869       proc = SoXtFullViewerP::sethomebuttonCB;
870       label[0] = 'N';
871       break;
872     case VIEW_ALL_BUTTON:
873       proc = SoXtFullViewerP::viewallbuttonCB;
874       label[0] = 'V';
875       break;
876     case SEEK_BUTTON:
877       proc = SoXtFullViewerP::seekbuttonCB;
878       label[0] = 'S';
879       break;
880     default:
881       assert(0);
882       break;
883     }
884     Widget button;
885     if (viewerbutton == EXAMINE_BUTTON || viewerbutton == INTERACT_BUTTON) {
886       button = XtVaCreateManagedWidget(label,
887                                        xmToggleButtonWidgetClass, parent,
888                                        XmNindicatorOn, False,
889                                        NULL);
890       if (viewerbutton == EXAMINE_BUTTON) {
891         XtVaSetValues(button, XmNset, this->isViewing() ? True : False, NULL);
892       }
893       if (viewerbutton == INTERACT_BUTTON) {
894         XtVaSetValues(button, XmNset, this->isViewing() ? False : True, NULL);
895       }
896     } else {
897       button = XtVaCreateManagedWidget(label,
898                                        xmPushButtonWidgetClass, parent,
899                                        NULL);
900     }
901 
902     switch (viewerbutton) {
903     case INTERACT_BUTTON:
904       PRIVATE(this)->viewerbuttons.pick = button;
905       break;
906     case EXAMINE_BUTTON:
907       PRIVATE(this)->viewerbuttons.view = button;
908       break;
909     case HOME_BUTTON:
910       PRIVATE(this)->viewerbuttons.home = button;
911       break;
912     case SET_HOME_BUTTON:
913       PRIVATE(this)->viewerbuttons.set_home = button;
914       break;
915     case VIEW_ALL_BUTTON:
916       PRIVATE(this)->viewerbuttons.view_all = button;
917       break;
918     case SEEK_BUTTON:
919       PRIVATE(this)->viewerbuttons.seek = button;
920       break;
921     default:
922       assert(0 && "impossible");
923       break;
924     }
925 #if HAVE_LIBXPM
926     Pixmap pixmap, pixmap_ins;
927     switch (viewerbutton) {
928     case INTERACT_BUTTON:
929       pixmap = PRIVATE(this)->pixmaps.pick =
930         SoXtInternal::createPixmapFromXpm(button, pick_xpm);
931       pixmap_ins = PRIVATE(this)->pixmaps.pick_ins =
932         SoXtInternal::createPixmapFromXpm(button, pick_xpm, TRUE);
933       break;
934     case EXAMINE_BUTTON:
935       pixmap = PRIVATE(this)->pixmaps.view =
936         SoXtInternal::createPixmapFromXpm(button, view_xpm);
937       pixmap_ins = PRIVATE(this)->pixmaps.view_ins =
938         SoXtInternal::createPixmapFromXpm(button, view_xpm, TRUE);
939       break;
940     case HOME_BUTTON:
941       pixmap = pixmap_ins = PRIVATE(this)->pixmaps.home =
942         SoXtInternal::createPixmapFromXpm(button, home_xpm);
943       break;
944     case SET_HOME_BUTTON:
945       pixmap = pixmap_ins = PRIVATE(this)->pixmaps.set_home =
946         SoXtInternal::createPixmapFromXpm(button, set_home_xpm);
947       break;
948     case VIEW_ALL_BUTTON:
949       pixmap = pixmap_ins = PRIVATE(this)->pixmaps.view_all =
950         SoXtInternal::createPixmapFromXpm(button, view_all_xpm);
951       break;
952     case SEEK_BUTTON:
953       pixmap = PRIVATE(this)->pixmaps.seek =
954         SoXtInternal::createPixmapFromXpm(button, seek_xpm);
955       pixmap_ins = PRIVATE(this)->pixmaps.seek_ins =
956         SoXtInternal::createPixmapFromXpm(button, seek_xpm, TRUE);
957       break;
958     default:
959       assert(0 && "impossible");
960       break;
961     }
962     if (pixmap && pixmap_ins) {
963       XtVaSetValues(button,
964                     XmNlabelType, XmPIXMAP,
965                     XmNlabelPixmap, pixmap,
966                     XmNlabelInsensitivePixmap, pixmap_ins,
967                     XmNselectPixmap, pixmap,
968                     XmNselectInsensitivePixmap, pixmap_ins,
969                     NULL);
970     }
971 #endif // HAVE_LIBXPM
972 
973     if (proc != NULL) {
974       if (viewerbutton == INTERACT_BUTTON || viewerbutton == EXAMINE_BUTTON) {
975         XtAddCallback(button, XmNdisarmCallback, proc, this);
976       } else {
977         XtAddCallback(button, XmNactivateCallback, proc, this);
978       }
979     }
980     if (buttonlist) buttonlist->append(button);
981   }
982 #if SOXT_DEBUG && 0
983   SoDebugError::postInfo("SoXtFullViewer::createViewerButtons", "[exit]");
984 #endif // SOXT_DEBUG
985 }
986 
987 /*!
988   FIXME: write doc
989 */
990 
991 void
buildPopupMenu(void)992 SoXtFullViewer::buildPopupMenu(void)
993 {
994   if (this->prefmenu == NULL)
995     this->prefmenu = PRIVATE(this)->setupStandardPopupMenu();
996 }
997 
998 /*!
999   FIXME: write doc
1000 */
1001 
1002 Widget
buildFunctionsSubmenu(Widget popup)1003 SoXtFullViewer::buildFunctionsSubmenu(Widget popup)
1004 {
1005   SOXT_STUB();
1006   return (Widget) NULL;
1007 }
1008 
1009 /*!
1010   FIXME: write doc
1011 */
1012 
1013 Widget
buildDrawStyleSubmenu(Widget popup)1014 SoXtFullViewer::buildDrawStyleSubmenu(Widget popup)
1015 {
1016   SOXT_STUB();
1017   return (Widget) NULL;
1018 }
1019 
1020 /*!
1021   FIXME: write doc
1022 */
1023 
1024 void
openPopupMenu(const SbVec2s position)1025 SoXtFullViewer::openPopupMenu(const SbVec2s position)
1026 {
1027   if (! this->isPopupMenuEnabled())
1028     return;
1029   if (this->prefmenu == NULL)
1030     this->buildPopupMenu();
1031   assert(this->prefmenu != NULL);
1032 #if SOXT_DEBUG && 0
1033   SoDebugError::postInfo("SoXtFullViewer::openPopupMenu", "[invoked]");
1034 #endif // SOXT_DEBUG && 0
1035 
1036   int x = position[0] + 2;
1037   int y = this->getGLSize()[1] - position[1] + 2;
1038 
1039   PRIVATE(this)->prepareMenu(this->prefmenu);
1040   this->prefmenu->popUp(this->getGLWidget(), x, y);
1041 }
1042 
1043 // *************************************************************************
1044 
1045 #ifndef DOXYGEN_SKIP_THIS
1046 void
leftWheelStartCB(Widget,XtPointer closure,XtPointer)1047 SoXtFullViewerP::leftWheelStartCB(Widget, XtPointer closure, XtPointer)
1048 {
1049   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1050   viewer->leftWheelStart();
1051 }
1052 
1053 void
leftWheelMotionCB(Widget,XtPointer closure,XtPointer call_data)1054 SoXtFullViewerP::leftWheelMotionCB(Widget, XtPointer closure, XtPointer call_data)
1055 {
1056   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1057   SoXtThumbWheelCallbackData * data = (SoXtThumbWheelCallbackData *) call_data;
1058   viewer->leftWheelMotion(data->current);
1059 }
1060 
1061 void
leftWheelFinishCB(Widget,XtPointer closure,XtPointer)1062 SoXtFullViewerP::leftWheelFinishCB(Widget, XtPointer closure, XtPointer)
1063 {
1064   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1065   viewer->leftWheelFinish();
1066 }
1067 
1068 void
bottomWheelStartCB(Widget,XtPointer closure,XtPointer)1069 SoXtFullViewerP::bottomWheelStartCB(Widget, XtPointer closure, XtPointer)
1070 {
1071   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1072   viewer->bottomWheelStart();
1073 }
1074 
1075 void
bottomWheelMotionCB(Widget,XtPointer closure,XtPointer call_data)1076 SoXtFullViewerP::bottomWheelMotionCB(Widget, XtPointer closure, XtPointer call_data)
1077 {
1078   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1079   SoXtThumbWheelCallbackData * data = (SoXtThumbWheelCallbackData *) call_data;
1080   viewer->bottomWheelMotion(data->current);
1081 }
1082 
1083 void
bottomWheelFinishCB(Widget,XtPointer closure,XtPointer)1084 SoXtFullViewerP::bottomWheelFinishCB(Widget, XtPointer closure, XtPointer)
1085 {
1086   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1087   viewer->bottomWheelFinish();
1088 }
1089 
1090 void
rightWheelStartCB(Widget,XtPointer closure,XtPointer)1091 SoXtFullViewerP::rightWheelStartCB(Widget, XtPointer closure, XtPointer)
1092 {
1093   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1094   viewer->rightWheelStart();
1095 }
1096 
1097 void
rightWheelMotionCB(Widget,XtPointer closure,XtPointer call_data)1098 SoXtFullViewerP::rightWheelMotionCB(Widget, XtPointer closure, XtPointer call_data)
1099 {
1100   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1101   SoXtThumbWheelCallbackData * data = (SoXtThumbWheelCallbackData *) call_data;
1102   viewer->rightWheelMotion(data->current);
1103 }
1104 
1105 void
rightWheelFinishCB(Widget,XtPointer closure,XtPointer)1106 SoXtFullViewerP::rightWheelFinishCB(Widget, XtPointer closure, XtPointer)
1107 {
1108   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1109   viewer->rightWheelFinish();
1110 }
1111 #endif DOXYGEN_SKIP_THIS
1112 
1113 // *************************************************************************
1114 
1115 /*!
1116   This method sets the label text displayed below the thumb wheel on the
1117   left decoration.
1118 */
1119 
1120 void
setLeftWheelString(const char * const string)1121 SoXtFullViewer::setLeftWheelString(const char * const string)
1122 {
1123 #if SOXT_DEBUG && 0
1124   SoDebugError::postInfo("SoXtFullViewer::setLeftWheelString",
1125                          "setting left wheel label");
1126 #endif // SOXT_DEBUG
1127   delete [] this->leftWheelStr;
1128   this->leftWheelStr = strcpy(new char [strlen(string)+1], string);
1129   if (this->leftWheelLabel != NULL)
1130     XtVaSetValues(this->leftWheelLabel,
1131       XtVaTypedArg,
1132         XmNlabelString, XmRString,
1133         this->leftWheelStr, strlen(this->leftWheelStr) + 1,
1134       NULL);
1135 }
1136 
1137 /*!
1138   This method sets the label text that is displayed to the left og the
1139   bottom decoration thumb wheel.
1140 */
1141 
1142 void
setBottomWheelString(const char * const string)1143 SoXtFullViewer::setBottomWheelString(const char * const string)
1144 {
1145 #if SOXT_DEBUG && 0
1146   SoDebugError::postInfo("SoXtFullViewer::setBottomWheelString",
1147                          "setting bottom wheel label");
1148 #endif // SOXT_DEBUG
1149   delete [] this->bottomWheelStr;
1150   this->bottomWheelStr = strcpy(new char [strlen(string)+1], string);
1151   if (this->bottomWheelLabel != NULL)
1152     XtVaSetValues(this->bottomWheelLabel,
1153       XtVaTypedArg,
1154         XmNlabelString, XmRString,
1155         this->bottomWheelStr, strlen(this->bottomWheelStr) + 1,
1156       NULL);
1157 }
1158 
1159 /*!
1160   This method sets the label text that is displayed under the right decoration
1161   thumb wheel.
1162 */
1163 
1164 void
setRightWheelString(const char * const string)1165 SoXtFullViewer::setRightWheelString(const char * const string)
1166 {
1167 #if SOXT_DEBUG && 0
1168   SoDebugError::postInfo("SoXtFullViewer::setRightWheelString", "[enter]");
1169 #endif // SOXT_DEBUG
1170 
1171   delete [] this->rightWheelStr;
1172   this->rightWheelStr = strcpy(new char [strlen(string)+1], string);
1173 
1174   if (this->rightWheelLabel != NULL)
1175     XtVaSetValues(this->rightWheelLabel,
1176       XtVaTypedArg,
1177         XmNlabelString, XmRString,
1178         this->rightWheelStr, strlen(this->rightWheelStr) + 1,
1179       NULL);
1180 
1181 #if SOXT_DEBUG && 0
1182   SoDebugError::postInfo("SoXtFullViewer::setRightWheelString", "[exit]");
1183 #endif // SOXT_DEBUG
1184 }
1185 
1186 const char *
getRightWheelString() const1187 SoXtFullViewer::getRightWheelString() const
1188 {
1189   return this->rightWheelStr;
1190 }
1191 
1192 // *************************************************************************
1193 
1194 #ifndef DOXYGEN_SKIP_THIS
1195 void
resetAppPushButtons(void)1196 SoXtFullViewerP::resetAppPushButtons(void)
1197 {
1198   int i;
1199   const int widgets = this->appButtonsList->getLength();
1200   for ( i = 0; i < widgets; i++ ) {
1201     Widget w = (Widget) (*(this->appButtonsList))[i];
1202     XtUnmanageChild(w);
1203   }
1204 }
1205 
1206 Widget
buildAppButtonsForm(Widget parent)1207 SoXtFullViewerP::buildAppButtonsForm(Widget parent)
1208 {
1209   Widget form = XtVaCreateManagedWidget("appbuttons",
1210                                         xmFormWidgetClass, parent,
1211                                         NULL);
1212   return form;
1213 }
1214 
1215 void
layoutAppPushButtons(void)1216 SoXtFullViewerP::layoutAppPushButtons(void)
1217 {
1218   int i;
1219   const int widgets = this->appButtonsList->getLength();
1220   Widget prev = NULL;
1221   for ( i = 0; i < widgets; i++ ) {
1222     Widget w = (Widget) (*(this->appButtonsList))[i];
1223     if ( i == 0 ) {
1224       XtVaSetValues(w,
1225         XmNhighlightThickness, 0,
1226         XmNtopAttachment, XmATTACH_FORM,
1227         XmNtopOffset, 0,
1228         XmNleftAttachment, XmATTACH_FORM,
1229         XmNleftOffset, 0,
1230         XmNrightAttachment, XmATTACH_FORM,
1231         XmNrightOffset, 0,
1232         XmNbottomOffset, 0,
1233         XmNwidth, 28,
1234         XmNheight, 28,
1235         NULL);
1236     } else {
1237       XtVaSetValues(w,
1238         XmNhighlightThickness, 0,
1239         XmNtopAttachment, XmATTACH_WIDGET,
1240         XmNtopWidget, prev,
1241         XmNleftAttachment, XmATTACH_FORM,
1242         XmNleftOffset, 0,
1243         XmNrightAttachment, XmATTACH_FORM,
1244         XmNrightOffset, 0,
1245         XmNbottomOffset, 0,
1246         XmNwidth, 28,
1247         XmNheight, 28,
1248         NULL);
1249     }
1250     XtManageChild(w);
1251     prev = w;
1252   }
1253   // SOXT_STUB();
1254 }
1255 
1256 // *************************************************************************
1257 
1258 // This method shows or hides the decoration widgets, depending on the
1259 // \a enable argument.
1260 void
showDecorationWidgets(SbBool enable)1261 SoXtFullViewerP::showDecorationWidgets(SbBool enable)
1262 {
1263   if (!this->canvas) return;
1264   assert(PUBLIC(this)->leftDecoration != (Widget) NULL);
1265   assert(PUBLIC(this)->rightDecoration != (Widget) NULL);
1266   assert(PUBLIC(this)->bottomDecoration != (Widget) NULL);
1267 
1268   if ( enable ) {
1269     XtVaSetValues(this->canvas,
1270                   XmNtopOffset, 0,
1271                   XmNleftOffset, 30,
1272                   XmNrightOffset, 30,
1273                   XmNbottomOffset, 30,
1274                   NULL);
1275     if ( XtWindow(PUBLIC(this)->leftDecoration) != 0 ) {
1276       XtMapWidget(PUBLIC(this)->leftDecoration);
1277       XtManageChild(PUBLIC(this)->leftDecoration);
1278     }
1279     if ( XtWindow(PUBLIC(this)->rightDecoration) != 0 ) {
1280       XtMapWidget(PUBLIC(this)->rightDecoration);
1281       XtManageChild(PUBLIC(this)->rightDecoration);
1282     }
1283     if ( XtWindow(PUBLIC(this)->bottomDecoration) != 0 ) {
1284       XtMapWidget(PUBLIC(this)->bottomDecoration);
1285       XtManageChild(PUBLIC(this)->bottomDecoration);
1286     }
1287   } else {
1288     if ( XtWindow(PUBLIC(this)->leftDecoration) != 0 ) {
1289       XtUnmapWidget(PUBLIC(this)->leftDecoration);
1290     }
1291     if ( XtWindow(PUBLIC(this)->rightDecoration) != 0 ) {
1292       XtUnmapWidget(PUBLIC(this)->rightDecoration);
1293     }
1294     if ( XtWindow(PUBLIC(this)->bottomDecoration) != 0 ) {
1295       XtUnmapWidget(PUBLIC(this)->bottomDecoration);
1296     }
1297     XtVaSetValues(this->canvas,
1298                   XmNtopOffset, 0,
1299                   XmNleftOffset, 0,
1300                   XmNrightOffset, 0,
1301                   XmNbottomOffset, 0,
1302                   NULL);
1303   }
1304 }
1305 
1306 // *************************************************************************
1307 
1308 void
selectedViewing(void)1309 SoXtFullViewerP::selectedViewing(void)
1310 {
1311   PUBLIC(this)->setViewing(PUBLIC(this)->isViewing() ? FALSE : TRUE);
1312 }
1313 
1314 void
selectedDecoration(void)1315 SoXtFullViewerP::selectedDecoration(void)
1316 {
1317   PUBLIC(this)->setDecoration(PUBLIC(this)->isDecoration() ? FALSE : TRUE);
1318 }
1319 
1320 void
selectedHeadlight(void)1321 SoXtFullViewerP::selectedHeadlight(void)
1322 {
1323   SOXT_STUB();
1324 }
1325 
1326 void
interactbuttonCB(Widget,XtPointer closure,XtPointer)1327 SoXtFullViewerP::interactbuttonCB(Widget, XtPointer closure, XtPointer)
1328 {
1329   SoXtFullViewer * viewer = (SoXtFullViewer *)closure;
1330   if (viewer->isViewing()) viewer->setViewing(FALSE);
1331 }
1332 
1333 void
examinebuttonCB(Widget,XtPointer closure,XtPointer)1334 SoXtFullViewerP::examinebuttonCB(Widget, XtPointer closure, XtPointer)
1335 {
1336   SoXtFullViewer * viewer = (SoXtFullViewer *)closure;
1337   if (!viewer->isViewing()) viewer->setViewing(TRUE);
1338 }
1339 
1340 void
homebuttonCB(Widget,XtPointer client_data,XtPointer)1341 SoXtFullViewerP::homebuttonCB(Widget, XtPointer client_data, XtPointer)
1342 {
1343   ((SoXtFullViewer *)client_data)->resetToHomePosition();
1344 }
1345 
1346 void
sethomebuttonCB(Widget,XtPointer client_data,XtPointer)1347 SoXtFullViewerP::sethomebuttonCB(Widget, XtPointer client_data, XtPointer)
1348 {
1349   ((SoXtFullViewer *)client_data)->saveHomePosition();
1350 }
1351 
1352 void
viewallbuttonCB(Widget,XtPointer client_data,XtPointer)1353 SoXtFullViewerP::viewallbuttonCB(Widget, XtPointer client_data, XtPointer)
1354 {
1355   ((SoXtFullViewer *)client_data)->viewAll();
1356 }
1357 
1358 void
seekbuttonCB(Widget,XtPointer client_data,XtPointer)1359 SoXtFullViewerP::seekbuttonCB(Widget, XtPointer client_data, XtPointer)
1360 {
1361   SoXtFullViewer * viewer = (SoXtFullViewer *)client_data;
1362   PRIVATE(viewer)->seekbuttonClicked();
1363 }
1364 
1365 // *************************************************************************
1366 
1367 void
increaseInteractiveCountCB(Widget,XtPointer closure,XtPointer)1368 SoXtFullViewerP::increaseInteractiveCountCB(Widget, XtPointer closure, XtPointer)
1369 {
1370   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1371   viewer->interactiveCountInc();
1372 }
1373 
1374 void
decreaseInteractiveCountCB(Widget,XtPointer closure,XtPointer)1375 SoXtFullViewerP::decreaseInteractiveCountCB(Widget, XtPointer closure, XtPointer)
1376 {
1377   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1378   viewer->interactiveCountDec();
1379 }
1380 
1381 // *************************************************************************
1382 
1383 void
speedIncCB(Widget,XtPointer closure,XtPointer)1384 SoXtFullViewerP::speedIncCB(Widget, XtPointer closure, XtPointer)
1385 {
1386   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1387   SOXT_STUB_ONCE();
1388 }
1389 
1390 void
speedDecCB(Widget,XtPointer closure,XtPointer)1391 SoXtFullViewerP::speedDecCB(Widget, XtPointer closure, XtPointer)
1392 {
1393   SoXtFullViewer * viewer = (SoXtFullViewer *) closure;
1394   SOXT_STUB_ONCE();
1395 }
1396 #endif // DOXYGEN_SKIP_THIS
1397 
1398 // *************************************************************************
1399 
1400 // doc in super
1401 void
sizeChanged(const SbVec2s & size)1402 SoXtFullViewer::sizeChanged(const SbVec2s & size)
1403 {
1404   SbVec2s newsize(size);
1405   if ( this->isDecoration() ) {
1406     newsize[0] = size[0] - 2 * 30;
1407     newsize[1] = size[1] - 30;
1408   }
1409   inherited::sizeChanged(newsize);
1410 }
1411 
1412 // *************************************************************************
1413 
1414 #ifndef DOXYGEN_SKIP_THIS
SoXtFullViewerP(SoXtFullViewer * publ)1415 SoXtFullViewerP::SoXtFullViewerP(SoXtFullViewer * publ)
1416   : SoGuiFullViewerP(publ)
1417 {
1418 }
1419 
~SoXtFullViewerP()1420 SoXtFullViewerP::~SoXtFullViewerP()
1421 {
1422 }
1423 
1424 void
seekbuttonClicked(void)1425 SoXtFullViewerP::seekbuttonClicked(void)
1426 {
1427   assert(PUBLIC(this)->isViewing() && "seek button should not be enabled in interaction mode");
1428   PUBLIC(this)->setSeekMode(PUBLIC(this)->isSeekMode() ? FALSE : TRUE);
1429 }
1430 
1431 void
setThumbWheelValue(void * wheel,float val)1432 SoXtFullViewerP::setThumbWheelValue(void * wheel, float val)
1433 {
1434   SoXtThumbWheelSetValue((Widget)wheel, val);
1435 }
1436 #endif // DOXYGEN_SKIP_THIS
1437 
1438 // *************************************************************************
1439 
1440 #undef PRIVATE
1441 #undef PUBLIC
1442