/* * * Copyright (C) 2000 Silicon Graphics, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * Further, this software is distributed without any warranty that it is * free of the rightful claim of any third person regarding infringement * or the like. Any license provided herein, whether implied or * otherwise, applies only to this software file. Patent licenses, if * any, provided herein do not apply to combinations of this program with * other software, or any other product whatsoever. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, * Mountain View, CA 94043, or: * * http://www.sgi.com * * For further information regarding this notice, see: * * http://oss.sgi.com/projects/GenInfo/NoticeExplan/ * */ /* * Copyright (C) 1990,91 Silicon Graphics, Inc. * _______________________________________________________________________ ______________ S I L I C O N G R A P H I C S I N C . ____________ | | $Revision: 1.1.1.1 $ | | Classes : SoXtFullViewer | | Author() : Alain Dumesny | ______________ S I L I C O N G R A P H I C S I N C . ____________ _______________________________________________________________________ */ // Define MENUS_IN_POPUP to get menus in the popup window #define MENUS_IN_POPUP #include #include #include #include #include #ifndef __sgi #define fsqrt sqrt #endif #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "SoXtBitmapButton.h" #include /* * Defines */ #define SCREEN(w) XScreenNumberOfScreen( XtScreen(w) ) // specifies the sizes for the decoration #define DECOR_SIZE 28 #define LABEL_SPACE 3 #define LABEL_SEPARATION 12 #define THUMB_SPACE 4 #define WHEEL_DOLLY_FACTOR 0.5 // list of the different popup choices enum popupChoices { VIEW_ALL = 20, // enables the same menu routine to be used SET_HOME, // as the draw style entrie (can't overlap HOME, // with SoXtViewerDrawStyle values) HEADLIGHT, SEEK, PREF, VIEWING, DECORATION, COPY_VIEW, PASTE_VIEW, HELP }; enum drawChoices { AS_IS, HIDDEN_LINE, NO_TXT, LOW_RES, LINE, POINT, BBOX, MOVE_SAME_AS, MOVE_NO_TXT, MOVE_LOW_RES, MOVE_LINE, MOVE_LOW_LINE, MOVE_POINT, MOVE_LOW_POINT, MOVE_BBOX, DRAW_STYLE_NUM // specify the length }; // list of the toggle buttons in the popumenu enum popupToggles { HEADLIGHT_WIDGET = 0, // very convenient to start at 0 VIEWING_WIDGET, DECORATION_WIDGET, POPUP_TOGGLE_NUM // specify the length }; // list of custom push buttons enum ViewerPushButtons { PICK_PUSH, VIEW_PUSH, HELP_PUSH, HOME_PUSH, SET_HOME_PUSH, VIEW_ALL_PUSH, SEEK_PUSH, PUSH_NUM }; enum ZoomSliderVars { ZOOM_LABEL, ZOOM_SLIDER, ZOOM_FIELD, ZOOM_RANGE_LAB1, ZOOM_RANGE_FIELD1, ZOOM_RANGE_LAB2, ZOOM_RANGE_FIELD2, ZOOM_NUM }; /* * Macros */ #define TOGGLE_ON(BUTTON) \ XmToggleButtonSetState((Widget) BUTTON, True, False) #define TOGGLE_OFF(BUTTON) \ XmToggleButtonSetState((Widget) BUTTON, False, False) static char *thisClassName = "SoXtFullViewer"; // Resources for labels. typedef struct { char *seekAniTime; char *seekToLabel; char *seekDistance; char *cameraZoom; char *zoomSlider; char *to; char *nearPlane; char *farPlane; char *cameraRotation; char *stereoErrorTitle; char *stereoError; char *preferences; char *viewerMenu; char *viewerSpeed; char *increase; char *decrease; } RES_LABELS; static RES_LABELS rl; static char *defaults[]={ "Seek animation time:", "Seek to:", "Seek distance:", "Camera Zoom:", "Zoom slider ranges from:", "to:", "near plane:", "far plane:", "camera rotation:", "Stereo Error Dialog", "Stereo Viewing can't be set on this machine.", "Preferences...", "Viewer Menu", "Viewer Speed:", " increase ", " decrease " }; //////////////////////////////////////////////////////////////////////// // // Constructor. // // Use: protected SoXtFullViewer::SoXtFullViewer( Widget parent, const char *name, SbBool buildInsideParent, SoXtFullViewer::BuildFlag buildFlag, SoXtViewer::Type t, SbBool buildNow) : SoXtViewer( parent, name, buildInsideParent, t, FALSE) // buildNow // //////////////////////////////////////////////////////////////////////// { int i; setClassName(thisClassName); setSize(SbVec2s(500, 390)); // default size firstBuild = TRUE; // used to get pref sheet resources only once // init decoration vars decorationFlag = (buildFlag & BUILD_DECORATION) != 0; mgrWidget = NULL; leftTrimForm = bottomTrimForm = rightTrimForm = NULL; rightWheelStr = bottomWheelStr = leftWheelStr = NULL; rightWheelLabel = bottomWheelLabel = leftWheelLabel = NULL; zoomSldRange.setValue(1, 140); // init pref sheet vars prefSheetShellWidget = NULL; prefSheetStr = NULL; zoomWidgets = new Widget[ZOOM_NUM]; for (i=0; iselect(viewingFlag); if (buttonList[PICK_PUSH]) buttonList[PICK_PUSH]->select(! viewingFlag); // update the popup menu entry if (popupToggleWidgets[VIEWING_WIDGET]) XmToggleButtonSetState(popupToggleWidgets[VIEWING_WIDGET], viewingFlag, False); } //////////////////////////////////////////////////////////////////////// // // Description: // redefine this to also update the popup menu // // Use: virtual public void SoXtFullViewer::setHeadlight(SbBool flag) // //////////////////////////////////////////////////////////////////////// { if (flag == isHeadlight()) return; // call base class routine SoXtViewer::setHeadlight(flag); // update the popup menu entry if (popupToggleWidgets[HEADLIGHT_WIDGET]) XmToggleButtonSetState(popupToggleWidgets[HEADLIGHT_WIDGET], isHeadlight(), False); } //////////////////////////////////////////////////////////////////////// // // Description: // redefine this to also update the popup menu // // Use: virtual public void SoXtFullViewer::setDrawStyle(SoXtViewer::DrawType type, SoXtViewer::DrawStyle style) // //////////////////////////////////////////////////////////////////////// { // call base class routine SoXtViewer::setDrawStyle(type, style); // update the popup menu entries if (drawStyleWidgets[0]) { for (int i = 0; i < DRAW_STYLE_NUM; i++) TOGGLE_OFF(drawStyleWidgets[i]); switch(getDrawStyle(SoXtViewer::STILL)) { case SoXtViewer::VIEW_AS_IS: TOGGLE_ON(drawStyleWidgets[AS_IS]); break; case SoXtViewer::VIEW_HIDDEN_LINE: TOGGLE_ON(drawStyleWidgets[HIDDEN_LINE]); break; case SoXtViewer::VIEW_NO_TEXTURE: TOGGLE_ON(drawStyleWidgets[NO_TXT]); break; case SoXtViewer::VIEW_LOW_COMPLEXITY: TOGGLE_ON(drawStyleWidgets[LOW_RES]); break; case SoXtViewer::VIEW_LINE: TOGGLE_ON(drawStyleWidgets[LINE]); break; case SoXtViewer::VIEW_POINT: TOGGLE_ON(drawStyleWidgets[POINT]); break; case SoXtViewer::VIEW_BBOX: TOGGLE_ON(drawStyleWidgets[BBOX]); break; } switch(getDrawStyle(SoXtViewer::INTERACTIVE)) { case SoXtViewer::VIEW_SAME_AS_STILL: TOGGLE_ON(drawStyleWidgets[MOVE_SAME_AS]); break; case SoXtViewer::VIEW_NO_TEXTURE: TOGGLE_ON(drawStyleWidgets[MOVE_NO_TXT]); break; case SoXtViewer::VIEW_LOW_COMPLEXITY: TOGGLE_ON(drawStyleWidgets[MOVE_LOW_RES]); break; case SoXtViewer::VIEW_LINE: TOGGLE_ON(drawStyleWidgets[MOVE_LINE]); break; case SoXtViewer::VIEW_LOW_RES_LINE: TOGGLE_ON(drawStyleWidgets[MOVE_LOW_LINE]); break; case SoXtViewer::VIEW_POINT: TOGGLE_ON(drawStyleWidgets[MOVE_POINT]); break; case SoXtViewer::VIEW_LOW_RES_POINT: TOGGLE_ON(drawStyleWidgets[MOVE_LOW_POINT]); break; case SoXtViewer::VIEW_BBOX: TOGGLE_ON(drawStyleWidgets[MOVE_BBOX]); break; } } } //////////////////////////////////////////////////////////////////////// // // Description: // redefine this to also update the popup menu // // Use: virtual public void SoXtFullViewer::setBufferingType(SoXtViewer::BufferType type) // //////////////////////////////////////////////////////////////////////// { // call base class routine SoXtViewer::setBufferingType(type); // update the popup menu entries if (bufferStyleWidgets[0]) { for (int i = 0; i < 3; i++) TOGGLE_OFF(bufferStyleWidgets[i]); TOGGLE_ON(bufferStyleWidgets[getBufferingType()]); } } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the camera to use (done in base class) and makes sure to // detach and re-attach() the zoom slider sensor. // // Use: virtual public void SoXtFullViewer::setCamera(SoCamera *newCamera) // //////////////////////////////////////////////////////////////////////// { // call base class routine SoXtViewer::setCamera(newCamera); // check if the zoom slider needs to be enabled if (zoomWidgets[ZOOM_SLIDER] != NULL) { SbBool enable = camera != NULL && camera->isOfType(SoPerspectiveCamera::getClassTypeId()); for (int i=0; iappend(newButton); // redo the layout again doAppButtonLayout(appButtonList->getLength() - 1); } //////////////////////////////////////////////////////////////////////// // // Description: // Insert a button in the application list at the given index // // Use: public void SoXtFullViewer::insertAppPushButton(Widget newButton, int index) // //////////////////////////////////////////////////////////////////////// { // add the button at the specified index appButtonList->insert(newButton, index); // redo the layout again doAppButtonLayout( appButtonList->find(newButton) ); } //////////////////////////////////////////////////////////////////////// // // Description: // Remove a button from the application list // // Use: public void SoXtFullViewer::removeAppPushButton(Widget oldButton) // //////////////////////////////////////////////////////////////////////// { // find the index where the button is int index = appButtonList->find(oldButton); if (index == -1) return; // remove from the list and redo the layout int lastIndex = appButtonList->getLength() - 1; appButtonList->remove(index); if (index != lastIndex) doAppButtonLayout(index); } //////////////////////////////////////////////////////////////////////// // // Description: // Redefines this to also hide the preference sheet. // // Use: virtual public void SoXtFullViewer::hide() // //////////////////////////////////////////////////////////////////////// { // call the parent class SoXtViewer::hide(); // destroy the pref sheet if it is currently on the screen if (prefSheetShellWidget != NULL) XtDestroyWidget(prefSheetShellWidget); } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the popup menu string // // use: protected void SoXtFullViewer::setPopupMenuString(const char *str) // //////////////////////////////////////////////////////////////////////// { if (popupTitle != NULL) free(popupTitle); popupTitle = (str != NULL) ? strdup(str) : NULL; } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the decoration bottom wheel string // // use: protected void SoXtFullViewer::setBottomWheelString(const char *str) // //////////////////////////////////////////////////////////////////////// { if (bottomWheelStr != NULL) free(bottomWheelStr); bottomWheelStr = (str != NULL) ? strdup(str) : NULL; if (bottomWheelStr != NULL && bottomWheelLabel != NULL) { Arg args[1]; XmString xmstr = XmStringCreateLocalized(bottomWheelStr); XtSetArg(args[0], XmNlabelString, xmstr); XtSetValues(bottomWheelLabel, args, 1); XmStringFree(xmstr); } } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the decoration left wheel string // // use: protected void SoXtFullViewer::setLeftWheelString(const char *str) // //////////////////////////////////////////////////////////////////////// { if (leftWheelStr != NULL) free(leftWheelStr); leftWheelStr = (str != NULL) ? strdup(str) : NULL; if (leftWheelStr != NULL && leftWheelLabel != NULL) { Arg args[1]; XmString xmstr = XmStringCreateLocalized(leftWheelStr); XtSetArg(args[0], XmNlabelString, xmstr); XtSetValues(leftWheelLabel, args, 1); XmStringFree(xmstr); } } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the decoration right wheel string // // use: protected void SoXtFullViewer::setRightWheelString(const char *str) // //////////////////////////////////////////////////////////////////////// { if (rightWheelStr != NULL) free(rightWheelStr); rightWheelStr = (str != NULL) ? strdup(str) : NULL; if (rightWheelStr != NULL && rightWheelLabel != NULL) { Arg args[1]; XmString xmstr = XmStringCreateLocalized(rightWheelStr); XtSetArg(args[0], XmNlabelString, xmstr); XtSetValues(rightWheelLabel, args, 1); XmStringFree(xmstr); } } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the viewer popup menu. // // Use: virtual protected void SoXtFullViewer::buildPopupMenu() // //////////////////////////////////////////////////////////////////////// { int n, butnum = 0; Arg args[12]; Widget buttons[15]; // create popup and register routine to pop the menu n = 0; #ifdef MENUS_IN_POPUP SoXt::getPopupArgs(XtDisplay(mgrWidget), SCREEN(mgrWidget), args, &n); #endif popupWidget = XmCreatePopupMenu(mgrWidget, "menu", args, n); #ifdef MENUS_IN_POPUP // register callbacks to load/unload the pulldown colormap when the // pulldown menu is posted. SoXt::registerColormapLoad(popupWidget, SoXt::getShellWidget(mgrWidget)); #endif XtAddEventHandler(mgrWidget, ButtonPressMask, FALSE, (XtEventHandler) &SoXtFullViewer::popMenuCallback, (XtPointer)this); // make a title label for the popup menu if (popupTitle == NULL) popupTitle = strdup( rl.viewerMenu ); buttons[butnum++] = XtCreateWidget(popupTitle, xmLabelGadgetClass, popupWidget, NULL, 0); buttons[butnum++] = XtCreateWidget("sep", xmSeparatorGadgetClass, popupWidget, NULL, 0); // // create the submenus // buttons[butnum++] = buildFunctionsSubmenu(popupWidget); buttons[butnum++] = buildDrawStyleSubmenu(popupWidget); // // add the toggle buttons // n = 0; XtSetArg(args[n], XmNuserData, this); n++; #define ADD_TOGGLE(NAME, W, ID, STATE) \ XtSetArg(args[n], XmNset, STATE); \ buttons[butnum++] = popupToggleWidgets[W] = XtCreateWidget(NAME, \ xmToggleButtonGadgetClass, popupWidget, args, n+1); \ XtAddCallback(popupToggleWidgets[W], XmNvalueChangedCallback, \ (XtCallbackProc) SoXtFullViewer::menuPick, (XtPointer) ID); ADD_TOGGLE("Viewing", VIEWING_WIDGET, VIEWING, isViewing()) ADD_TOGGLE("Decoration", DECORATION_WIDGET, DECORATION, isDecoration()) ADD_TOGGLE("Headlight", HEADLIGHT_WIDGET, HEADLIGHT, isHeadlight()) #undef ADD_TOGGLE // // add some more regular buttons // #define ADD_ENTRY(NAME, ID) \ buttons[butnum] = XtCreateWidget(NAME, xmPushButtonGadgetClass, popupWidget, args, n); \ XtAddCallback(buttons[butnum], XmNactivateCallback, \ (XtCallbackProc) SoXtFullViewer::menuPick, (XtPointer) ID); \ butnum++; ADD_ENTRY( rl.preferences, PREF) #undef ADD_ENTRY // manage children XtManageChildren(buttons, butnum); } //////////////////////////////////////////////////////////////////////// // // Description: // Builds function submenu - this include all of the viewer push // buttons plus any useful entries. // // Use: protected Widget SoXtFullViewer::buildFunctionsSubmenu(Widget popup) // //////////////////////////////////////////////////////////////////////// { int n, butnum = 0; Arg args[12]; Widget buttons[15]; // create a cascade menu entry which will bring the submenu Widget cascade = XtCreateWidget("Functions", xmCascadeButtonGadgetClass, popup, NULL, 0); // create the submenu widget n = 0; #ifdef MENUS_IN_POPUP SoXt::getPopupArgs(XtDisplay(popup),SCREEN(popup), args, &n); #endif Widget submenu = XmCreatePulldownMenu(popup, "functions", args, n); XtSetArg(args[0], XmNsubMenuId, submenu); XtSetValues(cascade, args, 1); // // create the menu entries // n = 0; XtSetArg(args[n], XmNuserData, this); n++; #define ADD_ENTRY(NAME, ID) \ buttons[butnum] = XtCreateWidget(NAME, xmPushButtonGadgetClass, submenu, args, n); \ XtAddCallback(buttons[butnum], XmNactivateCallback, \ (XtCallbackProc) SoXtFullViewer::menuPick, (XtPointer) ID); \ butnum++; ADD_ENTRY("Help", HELP) ADD_ENTRY("Home", HOME) ADD_ENTRY("Set Home", SET_HOME) ADD_ENTRY("View All", VIEW_ALL) ADD_ENTRY("Seek", SEEK) buttons[butnum++] = XtCreateWidget("sep", xmSeparatorGadgetClass, submenu, NULL, 0); ADD_ENTRY("Copy View", COPY_VIEW) ADD_ENTRY("Paste View", PASTE_VIEW) #undef ADD_ENTRY // manage children XtManageChildren(buttons, butnum); return cascade; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds drawing style submenu // // Use: protected Widget SoXtFullViewer::buildDrawStyleSubmenu(Widget popup) // //////////////////////////////////////////////////////////////////////// { int n, butnum = 0; Arg args[12]; Widget buttons[30]; // create a cascade menu entry which will bring the submenu Widget cascade = XtCreateWidget("Draw Style", xmCascadeButtonGadgetClass, popup, NULL, 0); // create the submenu widget n = 0; #ifdef MENUS_IN_POPUP SoXt::getPopupArgs(XtDisplay(popup), SCREEN(popup), args, &n); #endif Widget submenu = XmCreatePulldownMenu(popup, "draw style", args, n); XtSetArg(args[0], XmNsubMenuId, submenu); XtSetValues(cascade, args, 1); // // create the first part of this sub menu // n = 0; XtSetArg(args[n], XmNuserData, this); n++; XtSetArg(args[n], XmNindicatorType, XmONE_OF_MANY); n++; #define ADD_ENTRY(NAME, ID, STATE) \ XtSetArg(args[n], XmNset, STATE); \ buttons[butnum++] = drawStyleWidgets[ID] = XtCreateWidget(NAME, \ xmToggleButtonGadgetClass, submenu, args, n+1); \ XtAddCallback(drawStyleWidgets[ID], XmNvalueChangedCallback, \ (XtCallbackProc) SoXtFullViewer::drawStyleMenuPick, (XtPointer) ID); int drawType = getDrawStyle(SoXtViewer::STILL); ADD_ENTRY("as is", AS_IS, drawType == SoXtViewer::VIEW_AS_IS) ADD_ENTRY("hidden line", HIDDEN_LINE, drawType == SoXtViewer::VIEW_HIDDEN_LINE) ADD_ENTRY("no texture", NO_TXT, drawType == SoXtViewer::VIEW_NO_TEXTURE) ADD_ENTRY("low resolution", LOW_RES, drawType == SoXtViewer::VIEW_LOW_COMPLEXITY) ADD_ENTRY("wireframe", LINE, drawType == SoXtViewer::VIEW_LINE) ADD_ENTRY("points", POINT, drawType == SoXtViewer::VIEW_POINT) ADD_ENTRY("bounding box (no depth)", BBOX, drawType == SoXtViewer::VIEW_BBOX) buttons[butnum++] = XtCreateWidget("sep", xmSeparatorGadgetClass, submenu, NULL, 0); drawType = getDrawStyle(SoXtViewer::INTERACTIVE); ADD_ENTRY("move same as still", MOVE_SAME_AS, drawType == SoXtViewer::VIEW_SAME_AS_STILL) ADD_ENTRY("move no texture", MOVE_NO_TXT, drawType == SoXtViewer::VIEW_NO_TEXTURE) ADD_ENTRY("move low res", MOVE_LOW_RES, drawType == SoXtViewer::VIEW_LOW_COMPLEXITY) ADD_ENTRY("move wireframe", MOVE_LINE, drawType == SoXtViewer::VIEW_LINE) ADD_ENTRY("move low res wireframe (no depth)", MOVE_LOW_LINE, drawType == SoXtViewer::VIEW_LOW_RES_LINE) ADD_ENTRY("move points", MOVE_POINT, drawType == SoXtViewer::VIEW_POINT) ADD_ENTRY("move low res points (no depth)", MOVE_LOW_POINT, drawType == SoXtViewer::VIEW_LOW_RES_POINT) ADD_ENTRY("move bounding box (no depth)", MOVE_BBOX, drawType == SoXtViewer::VIEW_BBOX) #undef ADD_ENTRY buttons[butnum++] = XtCreateWidget("sep", xmSeparatorGadgetClass, submenu, NULL, 0); // // create the second part of this sub menu // #define ADD_ENTRY(NAME, ID) \ XtSetArg(args[n], XmNset, bufType == ID); \ buttons[butnum++] = bufferStyleWidgets[ID] = XtCreateWidget(NAME, \ xmToggleButtonGadgetClass, submenu, args, n+1); \ XtAddCallback(bufferStyleWidgets[ID], XmNvalueChangedCallback, \ (XtCallbackProc) SoXtFullViewer::bufferStyleMenuPick, (XtPointer) ID); int bufType = getBufferingType(); ADD_ENTRY("single buffer", SoXtViewer::BUFFER_SINGLE) ADD_ENTRY("double buffer", SoXtViewer::BUFFER_DOUBLE) ADD_ENTRY("interactive buffer", SoXtViewer::BUFFER_INTERACTIVE) #undef ADD_ENTRY // manage children XtManageChildren(buttons, butnum); return cascade; } //////////////////////////////////////////////////////////////////////// // // Description: // Deletes the viewer popup menu. // // Use: protected void SoXtFullViewer::destroyPopupMenu() // //////////////////////////////////////////////////////////////////////// { int i; // remove callback to pop it up XtRemoveEventHandler(mgrWidget, ButtonPressMask, FALSE, (XtEventHandler) &SoXtFullViewer::popMenuCallback, (XtPointer)this); // destroy the popup menu and reset the menu variables... XtDestroyWidget(popupWidget); popupWidget = NULL; for (i=0; igetResource("decoration", "Decoration", decorationFlag); // Get resources for preference sheet items. float val; SbBool flag; char *str; // seek... if (xr->getResource("seekAnimationTime", "SeekAnimationTime", val)) setSeekTime(val); if (xr->getResource("seekTo", "SeekTo", str)) { if (strcasecmp(str,"point") == 0) setDetailSeek(TRUE); else if (strcasecmp(str,"object") == 0) setDetailSeek(FALSE); } if (xr->getResource("seekDistanceUsage", "SeekDistanceUsage", str)) { if (strcasecmp(str,"percentage") == 0) seekDistAsPercentage = TRUE; else if (strcasecmp(str,"absolute") == 0) seekDistAsPercentage = FALSE; } // zoom slider... if (xr->getResource("zoomMin", "ZoomMin", val)) zoomSldRange[0] = val; if (xr->getResource("zoomMax", "ZoomMax", val)) zoomSldRange[1] = val; // auto clipping planes... if (xr->getResource("autoClipping", "AutoClipping", flag)) setAutoClipping(flag); // manual clipping planes... //??? what if camera is NULL? should we save the values somewhere? if (camera != NULL) { if (xr->getResource("nearDistance", "NearDistance", val)) camera->nearDistance = val; if (xr->getResource("farDistance", "FarDistance", val)) camera->farDistance = val; } // labels and messages. // if (!xr->getResource( "seekAniTime", "SeekAniTime", rl.seekAniTime )) rl.seekAniTime = defaults[0]; if (!xr->getResource( "seekToLabel", "SeekToLabel", rl.seekToLabel )) rl.seekToLabel = defaults[1]; if (!xr->getResource( "seekDistance", "SeekDistance", rl.seekDistance )) rl.seekDistance = defaults[2]; if (!xr->getResource( "cameraZoom", "CameraZoom", rl.cameraZoom )) rl.cameraZoom = defaults[3]; if (!xr->getResource( "zoomSlider", "ZoomSlider", rl.zoomSlider )) rl.zoomSlider = defaults[4]; if (!xr->getResource( "to", "To", rl.to )) rl.to = defaults[5]; if (!xr->getResource( "nearPlane", "NearPlane", rl.nearPlane )) rl.nearPlane = defaults[6]; if (!xr->getResource( "farPlane", "FarPlane", rl.farPlane )) rl.farPlane = defaults[7]; if (!xr->getResource( "cameraRotation", "CameraRotation", rl.cameraRotation )) rl.cameraRotation = defaults[8]; // if (!xr->getResource( "stereoErrorTitle", "StereoErrorTitle", rl.stereoErrorTitle )) rl.stereoErrorTitle = defaults[9]; if (!xr->getResource( "stereoError", "StereoError", rl.stereoError )) rl.stereoError = defaults[10]; // if (!xr->getResource( "preferences", "Preferences", rl.preferences )) rl.preferences = defaults[11]; if (!xr->getResource( "viewerMenu", "ViewerMenu", rl.viewerMenu )) rl.viewerMenu = defaults[12]; if (!xr->getResource( "viewerSpeed", "ViewerSpeed", rl.viewerSpeed )) rl.viewerSpeed = defaults[13]; if (!xr->getResource( "increase", "Increase", rl.increase )) rl.increase = defaults[14]; if (!xr->getResource( "decrease", "Decrease", rl.decrease )) rl.decrease = defaults[15]; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the basic Viewer Component widget, complete with // functionality of a SoXtFullViewerManip, pop-up menu, sliders, etc. // Builds all subwidgets, and does layout using motif // // Use: protected Widget SoXtFullViewer::buildWidget(Widget parent) // //////////////////////////////////////////////////////////////////////// { // // create a top level form to hold everything together // Arg args[8]; int n = 0; SbVec2s size = getSize(); if ((size[0] != 0) && (size[1] != 0)) { XtSetArg(args[n], XtNwidth, size[0]); n++; XtSetArg(args[n], XtNheight, size[1]); n++; } // ??? don't listen to resize request by children - because the // ??? form widget layout will force the size down. This will prevent // ??? the RenderArea to pop to 400x400 size (default ) after the user // ??? set an explicit smaller size. XtSetArg(args[n], XmNresizePolicy, XmRESIZE_NONE); n++; // Create the root widget and register it with a class name mgrWidget = XtCreateWidget(getWidgetName(), xmFormWidgetClass, parent, args, n); registerWidget(mgrWidget); // Get widget resources if (firstBuild) { SoXtResource xr(mgrWidget); getResources(&xr); firstBuild = FALSE; } // build the components raWidget = SoXtRenderArea::buildWidget(mgrWidget); if (decorationFlag) buildDecoration(mgrWidget); // // Layout // n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetValues(raWidget, args, n); // manage children decorationFlag = !decorationFlag; // enable routine to be called setDecoration(! decorationFlag); XtManageChild(raWidget); // build the popup menu if (popupEnabled) buildPopupMenu(); return mgrWidget; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the Decoration trim (thumbwheel, text, slider, buttons, ..). // // Use: virtual protected void SoXtFullViewer::buildDecoration(Widget parent) // //////////////////////////////////////////////////////////////////////// { int n; Arg args[12]; // build the trim sides leftTrimForm = buildLeftTrim(parent); bottomTrimForm = buildBottomTrim(parent); rightTrimForm = buildRightTrim(parent); // // layout // n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNheight, DECOR_SIZE); n++; XtSetValues(bottomTrimForm, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, DECOR_SIZE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetArg(args[n], XmNwidth, DECOR_SIZE); n++; XtSetValues(leftTrimForm, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, DECOR_SIZE); n++; XtSetArg(args[n], XmNleftAttachment, XmNONE); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNwidth, DECOR_SIZE); n++; XtSetValues(rightTrimForm, args, n); // ??? children are managed by setDecoration() // ??? which is called after this routine by buildWidget() } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the left thumbwheel // // Use: protected void SoXtFullViewer::buildLeftWheel(Widget parent) // //////////////////////////////////////////////////////////////////////// { int n; Arg args[12]; n = 0; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], SgNangleRange, 0); n++; XtSetArg(args[n], SgNunitsPerRotation, 360); n++; XtSetArg(args[n], SgNshowHomeButton, FALSE); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; leftWheel = SgCreateThumbWheel(parent, NULL, args, n); XtAddCallback(leftWheel, XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::leftWheelCB, (XtPointer) this); XtAddCallback(leftWheel, XmNdragCallback, (XtCallbackProc) SoXtFullViewer::leftWheelCB, (XtPointer) this); leftWheelVal = 0; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the left trim decoration // // Use: virtual protected Widget SoXtFullViewer::buildLeftTrim(Widget parent) // //////////////////////////////////////////////////////////////////////// { int n; Arg args[12]; // create a form to hold all the parts Widget form = XtCreateWidget("LeftTrimForm", xmFormWidgetClass, parent, NULL, 0); // create all the parts buildLeftWheel(form); Widget butForm = buildAppButtons(form); // // layout // n = 0; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, THUMB_SPACE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetValues(leftWheel, args, n); n = 0; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, leftWheel); n++; XtSetValues(butForm, args, n); // manage children XtManageChild(leftWheel); XtManageChild(butForm); return form; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the bottom trim decoration // // Use: virtual protected Widget SoXtFullViewer::buildBottomTrim(Widget parent) // //////////////////////////////////////////////////////////////////////// { int n; Arg args[12]; // create a form to hold all the parts Widget form = XtCreateWidget("BottomTrimForm", xmFormWidgetClass, parent, NULL, 0); // create all the parts if (rightWheelStr == NULL) rightWheelStr = strdup("Motion Z"); rightWheelLabel = XtCreateWidget(rightWheelStr, xmLabelGadgetClass, form, NULL, 0); if (bottomWheelStr == NULL) bottomWheelStr = strdup("Motion X"); bottomWheelLabel = XtCreateWidget(bottomWheelStr, xmLabelGadgetClass, form, NULL, 0); if (leftWheelStr == NULL) leftWheelStr = strdup("Motion Y"); leftWheelLabel = XtCreateWidget(leftWheelStr, xmLabelGadgetClass, form, NULL, 0); n = 0; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], SgNangleRange, 0); n++; XtSetArg(args[n], SgNunitsPerRotation, 360); n++; XtSetArg(args[n], SgNshowHomeButton, FALSE); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; bottomWheel = SgCreateThumbWheel(form, NULL, args, n); XtAddCallback(bottomWheel, XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::bottomWheelCB, (XtPointer) this); XtAddCallback(bottomWheel, XmNdragCallback, (XtCallbackProc) SoXtFullViewer::bottomWheelCB, (XtPointer) this); bottomWheelVal = 0; // // layout // // left corner n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, 5); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, THUMB_SPACE); n++; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetValues(leftWheelLabel, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, 5); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, leftWheelLabel); n++; XtSetArg(args[n], XmNleftOffset, LABEL_SEPARATION); n++; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetValues(bottomWheelLabel, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, THUMB_SPACE); n++; XtSetArg(args[n], XmNleftAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNleftWidget, bottomWheelLabel); n++; XtSetArg(args[n], XmNleftOffset, LABEL_SPACE); n++; XtSetArg(args[n], XmNrightAttachment, XmNONE); n++; XtSetValues(bottomWheel, args, n); // right corner n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomOffset, 5); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightOffset, THUMB_SPACE); n++; XtSetArg(args[n], XmNleftAttachment, XmNONE); n++; XtSetValues(rightWheelLabel, args, n); // manage children (order important) XtManageChild(leftWheelLabel); XtManageChild(bottomWheelLabel); XtManageChild(bottomWheel); XtManageChild(rightWheelLabel); return form; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the right trim decoration // // Use: virtual protected Widget SoXtFullViewer::buildRightTrim(Widget parent) // //////////////////////////////////////////////////////////////////////// { int n; Arg args[12]; // create a form to hold all the parts Widget form = XtCreateWidget("RightTrimForm", xmFormWidgetClass, parent, NULL, 0); // create all the parts n = 0; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], SgNangleRange, 0); n++; XtSetArg(args[n], SgNunitsPerRotation, 360); n++; XtSetArg(args[n], SgNshowHomeButton, FALSE); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNorientation, XmVERTICAL); n++; rightWheel = SgCreateThumbWheel(form, NULL, args, n); XtAddCallback(rightWheel, XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::rightWheelCB, (XtPointer) this); XtAddCallback(rightWheel, XmNdragCallback, (XtCallbackProc) SoXtFullViewer::rightWheelCB, (XtPointer) this); rightWheelVal = 0; Widget buttonForm = buildViewerButtons(form); // // layout // n = 0; XtSetArg(args[n], XmNtopAttachment, XmNONE); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNrightOffset, THUMB_SPACE); n++; XtSetArg(args[n], XmNleftAttachment, XmNONE); n++; XtSetValues(rightWheel, args, n); n = 0; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, rightWheel); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftAttachment, XmNONE); n++; XtSetValues(buttonForm, args, n); // manage children XtManageChild(rightWheel); XtManageChild(buttonForm); return form; } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the viewer buttons (all within a form) // // Use: protected Widget SoXtFullViewer::buildViewerButtons(Widget parent) // //////////////////////////////////////////////////////////////////////// { int i, num; Widget form, *list; Arg args[12]; // create a form to hold everything form = XtCreateWidget(NULL, xmFormWidgetClass, parent, NULL, 0); createViewerButtons(form); // get all the button widgets num = viewerButtonWidgets->getLength(); list = new Widget[num]; for (i=0; igetWidget(); XtVaSetValues(w, XmNuserData, this, NULL); XtAddCallback(w, XmNactivateCallback, (XtCallbackProc) SoXtFullViewer::pushButtonCB, (XtPointer) i); // add this button to the list... viewerButtonWidgets->append(w); } // set the button images buttonList[PICK_PUSH]->setIcon(so_xt_pick_bits, so_xt_icon_width, so_xt_icon_height); buttonList[VIEW_PUSH]->setIcon(so_xt_view_bits, so_xt_icon_width, so_xt_icon_height); buttonList[HELP_PUSH]->setIcon(so_xt_help_bits, so_xt_icon_width, so_xt_icon_height); buttonList[HOME_PUSH]->setIcon(so_xt_home_bits, so_xt_icon_width, so_xt_icon_height); buttonList[SET_HOME_PUSH]->setIcon(so_xt_set_home_bits, so_xt_icon_width, so_xt_icon_height); buttonList[VIEW_ALL_PUSH]->setIcon(so_xt_see_all_bits, so_xt_icon_width, so_xt_icon_height); buttonList[SEEK_PUSH]->setIcon(so_xt_seek_bits, so_xt_icon_width, so_xt_icon_height); // show the pick/view state if (isViewing()) buttonList[VIEW_PUSH]->select(TRUE); else buttonList[PICK_PUSH]->select(TRUE); } //////////////////////////////////////////////////////////////////////// // // Description: // Builds the app buttons form and any putton the application supplied // // Use: protected Widget SoXtFullViewer::buildAppButtons(Widget parent) // //////////////////////////////////////////////////////////////////////// { // create a form to hold the buttons appButtonForm = XtCreateWidget("AppButtForm", xmFormWidgetClass, parent, NULL, 0); // build all the buttons if ( appButtonList->getLength() > 0 ) doAppButtonLayout(0); return appButtonForm; } //////////////////////////////////////////////////////////////////////// // // Description: // Do the app push button build/layout/show withing the button's // form widget. Start at the given index // // Use: private void SoXtFullViewer::doAppButtonLayout(int start) // //////////////////////////////////////////////////////////////////////// { int i, num; Arg args[12]; Widget *widgetList, prevWidget; num = appButtonList->getLength() - start; widgetList = new Widget[num]; // build all the buttons for (i=0; i=0; i--) { if ( XtIsManaged(widgetList[i]) ) XtUnmanageChild(widgetList[i]); } if (start != 0) prevWidget = (Widget) ((*appButtonList)[start-1]); // // layout // XtSetArg(args[0], XmNrightAttachment, XmNONE); XtSetArg(args[1], XmNleftAttachment, XmATTACH_FORM); XtSetArg(args[2], XmNbottomAttachment, XmNONE); for (i=0; iisOfType(SoPerspectiveCamera::getClassTypeId()))); for (int i=0; iisOfType(SoPerspectiveCamera::getClassTypeId()) ) ((SoPerspectiveCamera *)camera)->heightAngle = zoom * M_PI / 180.0; else if ( camera->isOfType(SoOrthographicCamera::getClassTypeId()) ) ((SoOrthographicCamera *)camera)->height = zoom; #if DEBUG else SoDebugError::post("SoXtFullViewer::setCameraZoom", "unknown camera type"); #endif } //////////////////////////////////////////////////////////////////////// // // Description: // Gets the camera current zoom value. The value is returned in degrees // for a perspective camera. // // Use: private float SoXtFullViewer::getCameraZoom() // //////////////////////////////////////////////////////////////////////// { if (camera == NULL) return 0; if ( camera->isOfType(SoPerspectiveCamera::getClassTypeId()) ) return ((SoPerspectiveCamera *)camera)->heightAngle.getValue() * 180.0 / M_PI; else if ( camera->isOfType(SoOrthographicCamera::getClassTypeId()) ) return ((SoOrthographicCamera *)camera)->height.getValue(); else { #if DEBUG SoDebugError::post("SoXtFullViewer::getCameraZoom", "unknown camera type"); #endif return 0; } } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the zoom slider position based on the camera values using // the square root for the actual position. // // Use: private void SoXtFullViewer::setZoomSliderPosition(float zoom) // //////////////////////////////////////////////////////////////////////// { if (zoomWidgets[ZOOM_SLIDER] == NULL) return; // find the slider position, using a square root distance to make the // slider smoother and less sensitive when close to zero. float f = (zoom - zoomSldRange[0]) / (zoomSldRange[1] - zoomSldRange[0]); f = (f < 0) ? 0 : ((f > 1) ? 1 : f); f = fsqrt(f); // finally position the slider Arg args[1]; int val = int(f * 1000); XtSetArg(args[0], XmNvalue, val); XtSetValues(zoomWidgets[ZOOM_SLIDER], args, 1); } //////////////////////////////////////////////////////////////////////// // // Description: // Sets the zoom field value based on the current camera zoom value. // // Use: private void SoXtFullViewer::setZoomFieldString(float zoom) // //////////////////////////////////////////////////////////////////////// { if (zoomWidgets[ZOOM_FIELD] == NULL) return; Arg args[1]; char str[15]; sprintf(str, "%.1f", zoom); XtSetArg(args[0], XmNvalue, str); XtSetValues(zoomWidgets[ZOOM_FIELD], args, 1); } // // Virtual thumb wheels methods which subclasses can redefine // void SoXtFullViewer::rightWheelStart() { interactiveCountInc(); } void SoXtFullViewer::bottomWheelStart() { interactiveCountInc(); } void SoXtFullViewer::leftWheelStart() { interactiveCountInc(); } void SoXtFullViewer::rightWheelFinish() { interactiveCountDec(); } void SoXtFullViewer::bottomWheelFinish() { interactiveCountDec(); } void SoXtFullViewer::leftWheelFinish() { interactiveCountDec(); } void SoXtFullViewer::rightWheelMotion(float) {} void SoXtFullViewer::bottomWheelMotion(float) {} void SoXtFullViewer::leftWheelMotion(float) {} void SoXtFullViewer::openViewerHelpCard() {} // //////////////////////////////////////////////////////////////////////// // static callbacks stubs //////////////////////////////////////////////////////////////////////// // // // This static variable is used to detect start/finish callbacks // for the SgThumbwheel and the XmScale widgets. // static SbBool firstDrag = TRUE; // thumb wheel static value changed callbacks void SoXtFullViewer::rightWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->rightWheelStart(); firstDrag = FALSE; } v->rightWheelMotion( - data->value * M_PI / 180.0); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->rightWheelFinish(); firstDrag = TRUE; } } void SoXtFullViewer::bottomWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->bottomWheelStart(); firstDrag = FALSE; } v->bottomWheelMotion(data->value * M_PI / 180.0); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->bottomWheelFinish(); firstDrag = TRUE; } } void SoXtFullViewer::leftWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->leftWheelStart(); firstDrag = FALSE; } v->leftWheelMotion( - data->value * M_PI / 180.0); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->leftWheelFinish(); firstDrag = TRUE; } } // // viewer push button callbacks // void SoXtFullViewer::pushButtonCB(Widget w, int id, void *) { SoXtFullViewer *v; XtVaGetValues(w, XmNuserData, &v, NULL); switch (id) { case PICK_PUSH: v->setViewing(FALSE); break; case VIEW_PUSH: v->setViewing(TRUE); break; case HELP_PUSH: v->openViewerHelpCard(); break; case HOME_PUSH: v->resetToHomePosition(); break; case SET_HOME_PUSH: v->saveHomePosition(); break; case VIEW_ALL_PUSH: v->viewAll(); break; case SEEK_PUSH: v->setSeekMode(! v->isSeekMode()); break; } } void SoXtFullViewer::prefSheetDestroyCB(Widget, SoXtFullViewer *v, void *) { // reset our vars when the dialog gets destroyed.... v->prefSheetShellWidget = NULL; for (int i=0; izoomWidgets[i] = NULL; } void SoXtFullViewer::seekPrefSheetFieldCB(Widget field, SoXtFullViewer *v, void *) { // get text value from the label char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) ) { if (val < 0) val = 0; v->setSeekTime(val); } free(str); // reformat text field char valStr[10]; sprintf(valStr, "%.2f", v->getSeekTime()); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(XtParent(field), XmTRAVERSE_CURRENT); } void SoXtFullViewer::seekPrefSheetToggle1CB(Widget tog1, Widget tog2, void *) { XmToggleButtonSetState(tog2, !XmToggleButtonGetState(tog1), FALSE); // get viewer pointer and set seek detail state SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(tog1, args, 1); v->setDetailSeek( XmToggleButtonGetState(tog1) ); } void SoXtFullViewer::seekPrefSheetToggle2CB(Widget tog2, Widget tog1, void *) { XmToggleButtonSetState(tog1, !XmToggleButtonGetState(tog2), FALSE); // get viewer pointer and set seek detail state SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(tog1, args, 1); v->setDetailSeek( XmToggleButtonGetState(tog1) ); } void SoXtFullViewer::seekDistPercPrefSheetToggleCB(Widget tog1, Widget tog2, void *) { XmToggleButtonSetState(tog2, !XmToggleButtonGetState(tog1), FALSE); // get viewer pointer and set seek distance state SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(tog1, args, 1); v->seekDistAsPercentage = XmToggleButtonGetState(tog1); } void SoXtFullViewer::seekDistAbsPrefSheetToggleCB(Widget tog2, Widget tog1, void *) { XmToggleButtonSetState(tog1, !XmToggleButtonGetState(tog2), FALSE); // get viewer pointer and set seek distance state SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(tog1, args, 1); v->seekDistAsPercentage = XmToggleButtonGetState(tog1); } //////////////////////////////////////////////////////////////////////// // // Called whenever the user changes the zoom slider position. // // Use: static private // void SoXtFullViewer::zoomSliderCB(Widget, SoXtFullViewer *v, XtPointer *d) // //////////////////////////////////////////////////////////////////////// { XmScaleCallbackStruct *data = (XmScaleCallbackStruct *) d; // for the first move, invoke the start callbacks if (data->reason == XmCR_DRAG && firstDrag) { v->interactiveCountInc(); firstDrag = FALSE; } // if the slider is being dragged OR the slider jumps around // (user clicked left mouse on the side which causes the slider // to animate) update the camera zoom value. if (data->reason == XmCR_DRAG || (data->reason == XmCR_VALUE_CHANGED && firstDrag)) { // get the slider zoom value, taking the square value since we // are using the square root to make the slider smoother to use. float f = data->value / 1000.0; f *= f; float zoom = v->zoomSldRange[0] + f * (v->zoomSldRange[1] - v->zoomSldRange[0]); // now update the camera and text field v->setCameraZoom(zoom); v->setZoomFieldString(zoom); } // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks if (data->reason == XmCR_VALUE_CHANGED && ! firstDrag) { v->interactiveCountDec(); firstDrag = TRUE; } } //////////////////////////////////////////////////////////////////////// // // Called whenever the zoom slider field has a new value typed in. // // Use: static private // void SoXtFullViewer::zoomFieldCB(Widget field, SoXtFullViewer *v, XtPointer *) // //////////////////////////////////////////////////////////////////////// { // get value from the label char *str = XmTextGetString(field); float zoom; if ( sscanf(str, "%f", &zoom) && zoom > 0) { // check for valid perspective camera range if ( v->camera != NULL && v->camera->isOfType(SoPerspectiveCamera::getClassTypeId()) ) { zoom = (zoom < 0.01) ? 0.01 : ((zoom > 179.99) ? 179.99 : zoom); } // check if the newly typed value changed the slider range if (zoom < v->zoomSldRange[0]) v->zoomSldRange[0] = zoom; else if (zoom > v->zoomSldRange[1]) v->zoomSldRange[1] = zoom; // update the slider and camera zoom values. v->setCameraZoom(zoom); v->setZoomSliderPosition(zoom); } else zoom = v->getCameraZoom(); free(str); // always reformat text field v->setZoomFieldString(zoom); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } //////////////////////////////////////////////////////////////////////// // // This routine opens up the popup menu. // // Use: static private // void SoXtFullViewer::popMenuCallback(Widget, SoXtFullViewer *v, XEvent *event, Boolean *) // //////////////////////////////////////////////////////////////////////// { Arg args[1]; int button; XtSetArg(args[0], XmNwhichButton, &button); XtGetValues(v->popupWidget, args,1); if (event->xbutton.button == button) { XmMenuPosition(v->popupWidget, (XButtonPressedEvent *) event); XtManageChild(v->popupWidget); } } //////////////////////////////////////////////////////////////////////// // // Called by Xt when a main menu item is picked. // // Use: static private // void SoXtFullViewer::menuPick(Widget w, int id, XmAnyCallbackStruct *cb) // //////////////////////////////////////////////////////////////////////// { Time eventTime = cb->event->xbutton.time; SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(w, args, 1); switch(id) { case HELP: v->openViewerHelpCard(); break; case VIEW_ALL: v->viewAll(); break; case SET_HOME: v->saveHomePosition(); break; case HOME: v->resetToHomePosition(); break; case SEEK: v->setSeekMode(! v->isSeekMode()); break; case PREF: if (v->prefSheetShellWidget == NULL) v->createPrefSheet(); else SoXt::show(v->prefSheetShellWidget); break; case HEADLIGHT: v->setHeadlight(! v->isHeadlight()); break; case VIEWING: v->setViewing(! v->isViewing()); break; case DECORATION: v->setDecoration(! v->decorationFlag); break; case COPY_VIEW: v->copyView(eventTime); break; case PASTE_VIEW: v->pasteView(eventTime); break; } } //////////////////////////////////////////////////////////////////////// // // Called by Xt when a menu item is picked in the drawStyle menu. // // Use: static private // void SoXtFullViewer::drawStyleMenuPick(Widget w, int id, void *) // //////////////////////////////////////////////////////////////////////// { SoXtFullViewer *v; XtVaGetValues(w, XmNuserData, &v, NULL); switch(id) { case AS_IS: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_AS_IS); break; case HIDDEN_LINE: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_HIDDEN_LINE); break; case NO_TXT: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_NO_TEXTURE); break; case LOW_RES: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_LOW_COMPLEXITY); break; case LINE: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_LINE); break; case POINT: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_POINT); break; case BBOX: v->setDrawStyle(SoXtViewer::STILL, SoXtViewer::VIEW_BBOX); break; case MOVE_SAME_AS: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_SAME_AS_STILL); break; case MOVE_NO_TXT: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_NO_TEXTURE); break; case MOVE_LOW_RES: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_LOW_COMPLEXITY); break; case MOVE_LINE: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_LINE); break; case MOVE_LOW_LINE: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_LOW_RES_LINE); break; case MOVE_POINT: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_POINT); break; case MOVE_LOW_POINT: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_LOW_RES_POINT); break; case MOVE_BBOX: v->setDrawStyle(SoXtViewer::INTERACTIVE, SoXtViewer::VIEW_BBOX); break; } } //////////////////////////////////////////////////////////////////////// // // Called by Xt when a menu item in the buffer style menu is picked. // // Use: static private // void SoXtFullViewer::bufferStyleMenuPick(Widget w, int id, void *) // //////////////////////////////////////////////////////////////////////// { SoXtFullViewer *v; XtVaGetValues(w, XmNuserData, &v, NULL); v->setBufferingType((SoXtViewer::BufferType)id); } //////////////////////////////////////////////////////////////////////// // // Description: // Called by the auto clipping preference sheet to toggle auto clipping // and show/hide the extra manual set thumbwheels. // // Use: static private void SoXtFullViewer::clipPrefSheetToggleCB(Widget toggle, Widget parent, void *) // //////////////////////////////////////////////////////////////////////// { // get the viewer pointer SoXtFullViewer *v; Arg args[1]; XtSetArg(args[0], XmNuserData, &v); XtGetValues(toggle, args, 1); v->setAutoClipping( XmToggleButtonGetState(toggle) ); // check if toggle button is on or off if ( v->isAutoClipping() ) { XtDestroyWidget( v->clipWheelForm ); } else { Widget label[2], thumb[2], text[2]; Arg args[12]; int n; // create a form to hold everything together Widget form = XtCreateWidget("", xmFormWidgetClass, parent, NULL, 0); v->clipWheelForm = form; // create the labels label[0] = XtCreateWidget( rl.nearPlane, xmLabelGadgetClass, form, NULL, 0); label[1] = XtCreateWidget( rl.farPlane, xmLabelGadgetClass, form, NULL, 0); // allocate the thumbwheels n = 0; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], SgNangleRange, 0); n++; XtSetArg(args[n], SgNunitsPerRotation, 360); n++; XtSetArg(args[n], SgNshowHomeButton, FALSE); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; thumb[0] = SgCreateThumbWheel(form, NULL, args, n); thumb[1] = SgCreateThumbWheel(form, NULL, args, n); XtAddCallback(thumb[0], XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::clipNearWheelCB, (XtPointer) v); XtAddCallback(thumb[0], XmNdragCallback, (XtCallbackProc) SoXtFullViewer::clipNearWheelCB, (XtPointer) v); XtAddCallback(thumb[1], XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::clipFarWheelCB, (XtPointer) v); XtAddCallback(thumb[1], XmNdragCallback, (XtCallbackProc) SoXtFullViewer::clipFarWheelCB, (XtPointer) v); v->clipNearWheelVal = 0; v->clipFarWheelVal = 0; // allocate the text fields n = 0; char str[15]; float val = (v->camera != NULL) ? v->camera->nearDistance.getValue() : 0; sprintf(str, "%g", val); XtSetArg(args[0], XmNvalue, str); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNcolumns, 11); n++; v->clipNearField = text[0] = XtCreateWidget("", xmTextWidgetClass, form, args, n); val = (v->camera != NULL) ? v->camera->farDistance.getValue() : 0; sprintf(str, "%g", val); XtSetArg(args[0], XmNvalue, str); v->clipFarField = text[1] = XtCreateWidget("", xmTextWidgetClass, form, args, n); XtAddCallback(text[0], XmNactivateCallback, (XtCallbackProc) SoXtFullViewer::clipFieldCB, (XtPointer) v); XtAddCallback(text[1], XmNactivateCallback, (XtCallbackProc) SoXtFullViewer::clipFieldCB, (XtPointer) v); // layout n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, toggle); n++; XtSetArg(args[n], XmNtopOffset, 2); n++; XtSetValues(form, args, n); n = 0; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetValues(text[0], args, n); n = 0; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, text[0]); n++; XtSetValues(text[1], args, n); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[1], XmNbottomWidget, text[0]); n++; XtSetArg(args[n], XmNbottomOffset, 3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[4], XmNrightWidget, text[0]); n++; XtSetArg(args[n], XmNrightOffset, 3); n++; XtSetValues(thumb[0], args, n); XtSetArg(args[1], XmNbottomWidget, text[1]); XtSetArg(args[4], XmNrightWidget, text[1]); XtSetValues(thumb[1], args, n); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[1], XmNbottomWidget, thumb[0]); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[3], XmNrightWidget, thumb[0]); n++; XtSetArg(args[n], XmNrightOffset, 5); n++; XtSetValues(label[0], args, n); XtSetArg(args[1], XmNbottomWidget, thumb[1]); XtSetArg(args[3], XmNrightWidget, thumb[1]); XtSetValues(label[1], args, n); // manage children XtManageChild(form); XtManageChildren(text, 2); XtManageChildren(thumb, 2); XtManageChildren(label, 2); } } void SoXtFullViewer::clipNearWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { if (v->camera == NULL) return; SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->interactiveCountInc(); firstDrag = FALSE; } // shorter/grow the near plane distance given the wheel rotation float dist = v->camera->nearDistance.getValue(); dist *= powf(80.0, (data->value - v->clipNearWheelVal) / 360.0); v->clipNearWheelVal = data->value; // change the camera and update the text field v->camera->nearDistance = dist; char str[15]; sprintf(str, "%g", dist); XmTextSetString(v->clipNearField, str); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->interactiveCountDec(); firstDrag = TRUE; } } void SoXtFullViewer::clipFarWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { if (v->camera == NULL) return; SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->interactiveCountInc(); firstDrag = FALSE; } // shorter/grow the near plane distance given the wheel rotation float dist = v->camera->farDistance.getValue(); dist *= powf(80.0, (data->value - v->clipFarWheelVal) / 360.0); v->clipFarWheelVal = data->value; // change the camera and update the text field v->camera->farDistance = dist; char str[15]; sprintf(str, "%g", dist); XmTextSetString(v->clipFarField, str); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->interactiveCountDec(); firstDrag = TRUE; } } void SoXtFullViewer::clipFieldCB(Widget field, SoXtFullViewer *v, void *) { if (v->camera == NULL) return; // get text value from the label and update camera char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) && (val > 0 || v->camera->isOfType(SoOrthographicCamera::getClassTypeId()))) { if (field == v->clipNearField) v->camera->nearDistance = val; else v->camera->farDistance = val; } else { if (field == v->clipNearField) val = v->camera->nearDistance.getValue(); else val = v->camera->farDistance.getValue(); } free(str); // reformat text field char valStr[15]; sprintf(valStr, "%g", val); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } #ifdef __sgi static void destroyStereoInfoDialogCB(Widget dialog, void *, void *) { XtDestroyWidget(dialog); } // Resources for messages. typedef struct { char *str1; char *str2; char *str3; char *str4; char *str5; char *str6; char *title; } RES_MSGS; static RES_MSGS rm; static char *defmsgs[]={ "Please refer to the setmon man pages to set and restore the", "monitor stereo mode.", "On RealityEngine, try '/usr/gfx/setmon -n 1025x768_96s'", "On Indy/Indigo, try '/usr/gfx/setmon -n STR_TOP' (or STR_BOT, ", "depending on which half of the screen the viewer is).", "To restore the monitor try '/usr/gfx/setmon -n 72HZ' (or 60HZ).", "Stereo Usage Dialog" }; static void createStereoInfoDialog(Widget shell) { Widget dialog = XmCreateWarningDialog(shell, "Stereo Dialog", NULL, NULL); SoXtResource xr(dialog); if (!xr.getResource( "fvsimsgs1", "FvMsgs1", rm.str1 )) rm.str1 = defmsgs[0]; if (!xr.getResource( "fvsimsgs2", "FvMsgs2", rm.str2 )) rm.str2 = defmsgs[1]; if (!xr.getResource( "fvsimsgs3", "FvMsgs3", rm.str3 )) rm.str3 = defmsgs[2]; if (!xr.getResource( "fvsimsgs4", "FvMsgs4", rm.str4 )) rm.str4 = defmsgs[3]; if (!xr.getResource( "fvsimsgs5", "FvMsgs5", rm.str5 )) rm.str5 = defmsgs[4]; if (!xr.getResource( "fvsimsgs6", "FvMsgs6", rm.str6 )) rm.str6 = defmsgs[5]; if (!xr.getResource( "fvsititle", "FvTitle", rm.title )) rm.title = defmsgs[6]; Arg args[5]; XmString xmstr = XmStringCreateLocalized(rm.str1); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringCreateLocalized(rm.str2)); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringCreateLocalized(rm.str3)); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringCreateLocalized(rm.str4)); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringCreateLocalized(rm.str5)); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringSeparatorCreate()); xmstr = XmStringConcat(xmstr, XmStringCreateLocalized(rm.str6)); int n = 0; XtSetArg(args[n], XmNautoUnmanage, FALSE); n++; XtSetArg(args[n], XtNtitle, rm.title); n++; XtSetArg(args[n], XmNmessageString, xmstr); n++; XtSetValues( dialog, args, n ); XmStringFree(xmstr); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_CANCEL_BUTTON)); XtUnmanageChild(XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON)); // register callback to destroy (and not just unmap) the dialog XtAddCallback(dialog, XmNokCallback, (XtCallbackProc) destroyStereoInfoDialogCB, (XtPointer)NULL); XtManageChild(dialog); } #endif //////////////////////////////////////////////////////////////////////// // // Description: // Called by the stereo preference sheet to toggle stereo viewing // and show/hide the extra offset thumbwheel. // // Use: static private void SoXtFullViewer::stereoPrefSheetToggleCB(Widget toggle, Widget parent, void *) // //////////////////////////////////////////////////////////////////////// { // get the viewer pointer SoXtFullViewer *v; XtVaGetValues(toggle, XmNuserData, &v, NULL); // // checks to make sure stereo viewing can be set, else // grey the UI and bring and error message. // SbBool toggleState = XmToggleButtonGetState(toggle); SbBool sameState = (toggleState == v->isStereoViewing()); if (! sameState) v->setStereoViewing(toggleState); if (toggleState && ! v->isStereoViewing()) { TOGGLE_OFF(toggle); XtVaSetValues(toggle, XmNsensitive, FALSE, NULL); XtVaSetValues(v->stereoLabel, XmNsensitive, FALSE, NULL); SoXt::createSimpleErrorDialog(toggle, rl.stereoErrorTitle, rl.stereoError); return; } // show/hide the eye spacing thumbwheel if ( ! v->isStereoViewing() ) { if (v->stereoWheelForm != NULL) { XtDestroyWidget( v->stereoWheelForm ); v->stereoWheelForm = NULL; } } else { if (v->stereoWheelForm != NULL) return; Widget label, thumb, text; Arg args[12]; int n; // create a form to hold everything together Widget form = XtCreateWidget("Stereo thumb form", xmFormWidgetClass, parent, NULL, 0); v->stereoWheelForm = form; // create the label label = XtCreateWidget( rl.cameraRotation, xmLabelGadgetClass, form, NULL, 0); // allocate the thumbwheel n = 0; XtSetArg(args[n], XmNvalue, 0); n++; XtSetArg(args[n], SgNangleRange, 0); n++; XtSetArg(args[n], SgNunitsPerRotation, 360); n++; XtSetArg(args[n], SgNshowHomeButton, FALSE); n++; XtSetArg(args[n], XmNhighlightThickness, 0); n++; XtSetArg(args[n], XmNorientation, XmHORIZONTAL); n++; thumb = SgCreateThumbWheel(form, NULL, args, n); XtAddCallback(thumb, XmNvalueChangedCallback, (XtCallbackProc) SoXtFullViewer::stereoWheelCB, (XtPointer) v); XtAddCallback(thumb, XmNdragCallback, (XtCallbackProc) SoXtFullViewer::stereoWheelCB, (XtPointer) v); v->stereoWheelVal = 0; // allocate the text field n = 0; char str[15]; sprintf(str, "%.4f", v->getStereoOffset()); XtSetArg(args[n], XmNvalue, str); n++; XtSetArg(args[n], XmNhighlightThickness, 1); n++; XtSetArg(args[n], XmNcolumns, 6); n++; v->stereoField = text = XtCreateWidget("", xmTextWidgetClass, form, args, n); XtAddCallback(text, XmNactivateCallback, (XtCallbackProc) SoXtFullViewer::stereoFieldCB, (XtPointer) v); // layout n = 0; XtSetArg(args[n], XmNleftAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNleftOffset, 20); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNtopWidget, toggle); n++; XtSetArg(args[n], XmNtopOffset, 2); n++; XtSetValues(form, args, n); n = 0; XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++; XtSetArg(args[n], XmNtopAttachment, XmATTACH_FORM); n++; XtSetValues(text, args, n); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, text); n++; XtSetArg(args[n], XmNbottomOffset, 3); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, text); n++; XtSetArg(args[n], XmNrightOffset, 3); n++; XtSetValues(thumb, args, n); n = 0; XtSetArg(args[n], XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET); n++; XtSetArg(args[n], XmNbottomWidget, thumb); n++; XtSetArg(args[n], XmNrightAttachment, XmATTACH_WIDGET); n++; XtSetArg(args[n], XmNrightWidget, thumb); n++; XtSetArg(args[n], XmNrightOffset, 5); n++; XtSetValues(label, args, n); // manage children XtManageChild(form); XtManageChild(text); XtManageChild(thumb); XtManageChild(label); #ifdef __sgi // bring a dialog to tell the user to look at setmon to set // the monitor to stereo mode if (! sameState) createStereoInfoDialog(SoXt::getShellWidget(toggle)); #endif } } void SoXtFullViewer::stereoWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; if (data->reason == XmCR_DRAG) { // for the first move, invoke the start callbacks if (firstDrag) { v->interactiveCountInc(); firstDrag = FALSE; } // shorter/grow the stereo camera offset v->setStereoOffset( v->getStereoOffset() * powf(80.0, (data->value - v->stereoWheelVal) / 360.0) ); v->stereoWheelVal = data->value; // update the text field char str[15]; sprintf(str, "%.4f", v->getStereoOffset()); XmTextSetString(v->stereoField, str); v->scheduleRedraw(); } else { // reason = XmCR_VALUE_CHANGED, invoke the finish callbacks v->interactiveCountDec(); firstDrag = TRUE; } } void SoXtFullViewer::stereoFieldCB(Widget field, SoXtFullViewer *v, void *) { // get text value from the label and update camera char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) && val > 0) { v->setStereoOffset(val); v->scheduleRedraw(); } free(str); // reformat text field char valStr[10]; sprintf(valStr, "%.4f", v->getStereoOffset()); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } void SoXtFullViewer::seekDistWheelCB(Widget, SoXtFullViewer *v, XtPointer *d) { SgThumbWheelCallbackStruct *data = (SgThumbWheelCallbackStruct *) d; // shorter/grow the seek distance given the wheel rotation v->seekDistance *= powf(80.0, (data->value - v->seekDistWheelVal) / 360.0); v->seekDistWheelVal = data->value; // update the text field char str[15]; sprintf(str, "%.3g", v->seekDistance); XmTextSetString(v->seekDistField, str); } void SoXtFullViewer::seekDistFieldCB(Widget field, SoXtFullViewer *v, void *) { // get text value from the label char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) && val > 0) v->seekDistance = val; else val = v->seekDistance; free(str); // reformat text field char valStr[15]; sprintf(valStr, "%.3g", val); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } void SoXtFullViewer::zoomPrefSheetMinFieldCB(Widget field, SoXtFullViewer *v, void *) { // get text value from the label char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) && val >= 0) { // check for valid perspective camera range if ( v->camera != NULL && v->camera->isOfType(SoPerspectiveCamera::getClassTypeId()) ) { val = (val < 0.01) ? 0.01 : ((val > 178.99) ? 178.99 : val); } // finally update the slider to reflect the changes v->zoomSldRange[0] = val; v->setZoomSliderPosition( v->getCameraZoom() ); } else val = v->zoomSldRange[0]; free(str); // reformat text field char valStr[15]; sprintf(valStr, "%.1f", val); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } void SoXtFullViewer::zoomPrefSheetMaxFieldCB(Widget field, SoXtFullViewer *v, void *) { // get text value from the field char *str = XmTextGetString(field); float val; if ( sscanf(str, "%f", &val) && val >= 0) { // check for valid perspective camera range if ( v->camera != NULL && v->camera->isOfType(SoPerspectiveCamera::getClassTypeId()) ) { val = (val < 1.01) ? 1.01 : ((val > 179.99) ? 179.99 : val); } // finally update the slider to reflect the changes v->zoomSldRange[1] = val; v->setZoomSliderPosition( v->getCameraZoom() ); } else val = v->zoomSldRange[1]; free(str); // reformat text field char valStr[15]; sprintf(valStr, "%.1f", val); XmTextSetString(field, valStr); // make the text field loose the focus XmProcessTraversal(SoXt::getShellWidget(field), XmTRAVERSE_CURRENT); } void SoXtFullViewer::speedIncPrefSheetButtonCB(Widget, SoXtFullViewer *p, void *) { p->viewerSpeed *= 2.0; } void SoXtFullViewer::speedDecPrefSheetButtonCB(Widget, SoXtFullViewer *p, void *) { p->viewerSpeed /= 2.0; } #undef SCREEN