1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2005 by Systems in Motion. All rights reserved.
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.
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 Systems in Motion about acquiring
15
* a Coin Professional Edition License.
17
* See <URL:http://www.coin3d.org/> for more information.
19
* Systems in Motion, Postboks 1283, Pirsenteret, 7462 Trondheim, NORWAY.
20
* <URL:http://www.sim.no/>.
22
\**************************************************************************/
24
// src/Inventor/Qt/viewers/SoQtFullViewer.cpp. Generated from SoGuiFullViewer.cpp.in by configure.
26
// This file contains the generic, "templatize-able" parts of the
27
// So*FullViewer sourcecode.
30
\class SoQtFullViewer SoQtFullViewer.h Inventor/Qt/viewers/SoQtFullViewer.h
31
\brief The SoQtFullViewer class adds some user interface components to the viewer canvas.
32
\ingroup components viewers
34
The SoQtFullViewer is an abstract viewer class which extends it's
35
superclass (the basic SoQtViewer class) with two major user
40
<li>decorations around the render canvas, with buttons and
41
thumbwheels to control camera interaction and various other aspects
42
of model / scene viewing</li>
44
<li>a popup menu, invoked with the right mouse button, which
45
controls yet more aspects of the rendering and the viewer</li>
49
The user interface features listed above are the common parts of the
50
user interfaces of the SoQtFullViewer's non-abstract subclasses.
52
For "real" application programs, the viewers / components from this
53
class onwards and further down in the inheritance hierarchy is
54
usually not all that interesting, as they enforces too much extra
55
user interface cruft not compatible with the look and feel of the
56
other parts of the application user interface. So most "real"
57
applications will use either the SoQtViewer or the
58
SoQtRenderArea as their base-level component, and then inherit
59
one of these down into one's own "proper" viewer classes.
61
The non-abstract subclasses of the SoQtFullViewer class are
62
viewer components often used as a test-bed for prototyping / rapid
63
application development when doing quick testing of scenes,
64
stand-alone 3D-models, animation techniques, etc etc.
67
\sa SoQtConstrainedViewer, SoQtExaminerViewer, SoQtPlaneViewer
71
// *************************************************************************
75
#include <Inventor/Qt/viewers/SoQtFullViewer.h>
76
#include <Inventor/Qt/viewers/SoQtFullViewerP.h>
77
#include <Inventor/Qt/widgets/SoQtPopupMenu.h>
80
#include <Inventor/events/SoMouseButtonEvent.h>
81
#include <Inventor/events/SoKeyboardEvent.h>
82
#include <Inventor/errors/SoDebugError.h>
83
#include <Inventor/nodes/SoOrthographicCamera.h>
84
#include <Inventor/nodes/SoPerspectiveCamera.h>
88
#endif // HAVE_CONFIG_H
90
// ************************************************************************
92
#define PRIVATE(o) (o->pimpl)
93
#define PUBLIC(o) (o->pub)
95
// ************************************************************************
97
// Note: the following function documentation block will also be used
98
// for all the miscellaneous viewer subclasses, so keep it general.
100
\fn void SoQtFullViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
102
Set up the viewer buttons with pixmaps and event connections.
105
One important note if you want to override this method to add your
106
own buttons to the list (in the explanation below, it is assumed
107
that you know how virtual function table pointers are handled by
110
createViewerButtons() is called (indirectly) from the constructors
111
of the viewer classes. This means that you need to delay it's
112
invocation until your own subclass's constructor is run, because
113
otherwise your re-implementation won't have been added to the
114
internal virtual function table yet.
116
Delaying a superclass viewer from building it's decorations is done
117
by passing build==FALSE as the last argument of the protected
118
constructors. You will then have to explicitly trigger the building
119
in your own constructor.
121
Here's a minimal example that shows the steps needed to be able to
122
override createViewerButtons() from SoQtExaminerViewer:
125
class MyExaminerViewer : public SoQtExaminerViewer {
128
MyExaminerViewer(QWidget * parent);
131
virtual void createViewerButtons(QWidget * parent, SbPList * buttonlist);
134
MyExaminerViewer::MyExaminerViewer(QWidget * parent)
135
: SoQtExaminerViewer(parent, NULL, TRUE,
136
SoQtFullViewer::BUILD_ALL, SoQtFullViewer::BROWSER,
137
// build == FALSE, to delay creation of decorations
140
// Explicitly trigger the construction of viewer decorations.
141
QWidget * widget = this->buildWidget(this->getParentWidget());
142
this->setBaseWidget(widget);
146
MyExaminerViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
148
SoQtExaminerViewer::createViewerButtons(parent, buttonlist);
149
// [now add your own button(s) to the buttonlist]
155
\enum SoQtFullViewer::BuildFlag
157
Valid values for the constructor argument that decides how much of
158
the user interface features to set up. The enum values are bitflags
159
that can be OR'ed together.
162
\var SoQtFullViewer::BuildFlag SoQtFullViewer::BUILD_NONE
164
Do not add any of the user interface components.
167
\var SoQtFullViewer::BuildFlag SoQtFullViewer::BUILD_DECORATION
169
Only build and set up the decorations around the OpenGL canvas.
172
\var SoQtFullViewer::BuildFlag SoQtFullViewer::BUILD_POPUP
174
Only build the popup menu. (Activated with the right mousebutton.)
177
\var SoQtFullViewer::BuildFlag SoQtFullViewer::BUILD_ALL
179
Build all user interface components of the SoQtFullViewer.
183
\var QWidget * SoQtFullViewer::leftDecoration
184
The root widget for the left-side decorations.
188
\var QWidget * SoQtFullViewer::leftWheel
189
The widget representing the thumbwheel left of the render canvas.
193
\var QWidget * SoQtFullViewer::leftWheelLabel
194
Label widget of left wheel.
198
\var char * SoQtFullViewer::leftWheelStr
199
Text of left thumbwheel's label.
203
\var float SoQtFullViewer::leftWheelVal
204
Current value of the left thumbwheel.
208
\var QWidget * SoQtFullViewer::bottomDecoration
209
The root widget for the bottom decorations.
213
\var QWidget * SoQtFullViewer::bottomWheel
214
The widget representing the thumbwheel below the render canvas.
218
\var QWidget * SoQtFullViewer::bottomWheelLabel
219
Label widget of bottom wheel.
223
\var char * SoQtFullViewer::bottomWheelStr
224
Text of bottom thumbwheel's label.
228
\var float SoQtFullViewer::bottomWheelVal
229
Current value of the bottom thumbwheel.
233
\var QWidget * SoQtFullViewer::rightDecoration
234
The root widget for the right-side decorations.
238
\var QWidget * SoQtFullViewer::rightWheel
239
The widget representing the thumbwheel on the right side of the render canvas.
243
\var QWidget * SoQtFullViewer::rightWheelLabel
244
Label widget of right wheel.
248
\var char * SoQtFullViewer::rightWheelStr
249
Text of right thumbwheel's label.
253
\var float SoQtFullViewer::rightWheelVal
254
Current value of the right-side thumbwheel.
258
\var SoQtPopupMenu * SoQtFullViewer::prefmenu
259
Pointer to the popup menu instance.
263
\fn SoQtFullViewer::SoQtFullViewer(QWidget * parent, const char * name, SbBool embed, SoQtFullViewer::BuildFlag buildFlag, SoQtViewer::Type type, SbBool build)
265
Constructor. See parent class for explanation of arguments.
267
Subclasses will probably usually call with the \a buildNow flag set
268
to \c FALSE to be able to do delayed building of the OpenGL canvas
269
after other setup tasks has been performed.
273
\fn SoQtFullViewer::~SoQtFullViewer()
279
\fn void SoQtFullViewer::setDecoration(const SbBool enable)
281
Turn the viewer decorations on or off.
287
\fn SbBool SoQtFullViewer::isDecoration(void) const
289
Return \c TRUE if the viewer decorations are on, otherwise \c FALSE.
295
\fn void SoQtFullViewer::setPopupMenuEnabled(const SbBool enable)
297
Decide whether or not if clicking with the right mouse button on
298
the OpenGL canvas should reveal a preferences popup menu when in
301
\sa isPopupMenuEnabled()
305
\fn SbBool SoQtFullViewer::isPopupMenuEnabled(void) const
307
Return \c TRUE if the popup preferences menu is enabled,
310
\sa setPopupMenuEnabled()
314
\fn QWidget * SoQtFullViewer::getAppPushButtonParent(void) const
316
Returns the widget which is used as the parent of application
317
specified buttons. The row of application buttons (if any) will be
318
placed in the upper left corner.
320
\sa addAppPushButton(), insertAppPushButton(), removeAppPushButton()
324
\fn void SoQtFullViewer::addAppPushButton(QWidget * newButton)
326
Add an application specific push button to the viewer decorations.
327
Application buttons will be laid out in a vertical row from the
330
The button will be added bottom-most.
332
\sa insertAppPushButton(), removeAppPushButton(), getAppPushButtonParent()
336
\fn void SoQtFullViewer::insertAppPushButton(QWidget * newButton, int index)
338
Insert an application specific push button to the viewer decorations
339
at the given \c index.
341
\sa addAppPushButton(), removeAppPushButton(), getAppPushButtonParent()
345
\fn void SoQtFullViewer::removeAppPushButton(QWidget * oldButton)
347
Remove one of the application specific buttons.
349
\sa addAppPushButton(), insertAppPushButton()
353
\fn int SoQtFullViewer::findAppPushButton(QWidget * oldButton) const
355
Return the index of a particular button that has been specified by
356
the application, or -1 of the button has not been added.
358
\sa addAppPushButton()
362
\fn int SoQtFullViewer::lengthAppPushButton(void) const
364
Return number of application specific buttons added.
366
\sa addAppPushButton(), insertAddAppPushButton()
370
\fn QWidget * SoQtFullViewer::getRenderAreaWidget(void) const
372
Returns the render area OpenGL canvas widget.
376
\fn void SoQtFullViewer::buildDecoration(QWidget * parent)
378
Build viewer decorations.
382
\fn QWidget * SoQtFullViewer::buildLeftTrim(QWidget * parent)
384
Build decorations on the left of the render canvas. Override this
385
method in subclasses if you want your own decorations on the viewer
388
The decoration will be 30 pixels wide.
392
\fn QWidget * SoQtFullViewer::buildBottomTrim(QWidget * parent)
394
Build decorations on the bottom of the render canvas. Override this
395
method in subclasses if you want your own decorations on the viewer window.
399
\fn QWidget * SoQtFullViewer::buildRightTrim(QWidget * parent)
401
Build decorations on the right side of the render canvas. Override this
402
method in subclasses if you want your own decorations on the viewer window.
406
\fn QWidget * SoQtFullViewer::buildAppButtons(QWidget * parent)
408
Build the application specified button row (if any buttons were
413
\fn QWidget * SoQtFullViewer::buildViewerButtons(QWidget * parent)
415
Build and layout viewer specified button row.
419
\fn void SoQtFullViewer::buildPopupMenu(void)
421
Make a popup menu with preferences settings.
423
One important note as for when you want to override this function in
424
a subclass: be aware that it will usually be invoked (indirectly)
425
from this class's constructor. That is \e before the table of
426
virtual function pointers has been set up for the subclass, and
427
because of this, the function will not be called in the subclass
428
even though it is virtual.
430
To make the overriding actually be in effect, you need to delay
431
building the widgets of this class. For information on how to do
432
that, see the documentation of
433
SoQtFullViewer::createViewerButtons().
437
\fn void SoQtFullViewer::openPopupMenu(const SbVec2s position)
439
NOTE: This method is not part of the original InventorXt API.
443
\fn void SoQtFullViewer::setLeftWheelString(const char * const string)
445
Set label of the left thumbwheel.
449
\fn void SoQtFullViewer::setBottomWheelString(const char * const string)
451
Set label of the bottom thumbwheel.
455
\fn void SoQtFullViewer::setRightWheelString(const char * const string)
457
Set label of the right thumbwheel.
460
// ************************************************************************
462
// Note: the following function documentation blocks for thumbwheel
463
// handling will also be used for all the miscellaneous viewer
464
// subclasses, so keep'em general.
467
Called when the user start to drag the thumbwheel in the left
468
frame. Override this method in subclassed viewers to provide your
469
own functionality on the thumbwheel.
471
\sa leftWheelMotion(), leftWheelFinish()
472
\sa bottomWheelStart(), rightWheelStart()
475
SoQtFullViewer::leftWheelStart(void)
477
this->interactiveCountInc();
481
Called repeatedly as the user drags the thumbwheel in the left
482
frame. Override this method in subclassed viewers to provide your
483
own functionality on the thumbwheel.
485
\sa leftWheelStart(), leftWheelFinish()
486
\sa bottomWheelStart(), rightWheelStart()
489
SoQtFullViewer::leftWheelMotion(float value)
491
this->leftWheelVal = value;
495
Called as the user let go of the thumbwheel in the left frame
496
after a drag operation. Override this method in subclassed viewers
497
to provide your own functionality on the thumbwheel.
499
\sa leftWheelStart(), leftWheelMotion()
500
\sa bottomWheelStart(), rightWheelStart()
503
SoQtFullViewer::leftWheelFinish(void)
505
this->interactiveCountDec();
509
Set a new value for the left thumbwheel.
512
SoQtFullViewer::setLeftWheelValue(const float value)
514
this->leftWheelVal = value;
515
// Wheel may not be constructed yet, but we need to be robust, as
516
// set*WheelValue() is used from subclasses.
517
if (this->leftWheel) {
518
SoQtFullViewerP::setThumbWheelValue(this->leftWheel, value);
523
Get current value of the left thumbwheel.
525
\sa leftWheelMotion()
528
SoQtFullViewer::getLeftWheelValue(void) const
530
return this->leftWheelVal;
534
Called when the user start to drag the thumbwheel in the bottom
535
frame. Override this method in subclassed viewers to provide your
536
own functionality on the thumbwheel.
538
\sa bottomWheelMotion(), bottomWheelFinish()
539
\sa leftWheelStart(), rightWheelStart()
542
SoQtFullViewer::bottomWheelStart(void)
544
this->interactiveCountInc();
548
Called repeatedly as the user drags the thumbwheel in the bottom
549
frame. Override this method in subclassed viewers to provide your
550
own functionality on the thumbwheel.
552
\sa bottomWheelStart(), bottomWheelFinish()
553
\sa leftWheelStart(), rightWheelStart()
556
SoQtFullViewer::bottomWheelMotion(float value)
558
this->bottomWheelVal = value;
562
Called as the user let go of the thumbwheel in the bottom frame
563
after a drag operation. Override this method in subclassed viewers
564
to provide your own functionality on the thumbwheel.
566
\sa bottomWheelStart(), bottomWheelMotion()
567
\sa leftWheelStart(), rightWheelStart()
570
SoQtFullViewer::bottomWheelFinish(void)
572
this->interactiveCountDec();
576
Set a new value for the bottom thumbwheel.
579
SoQtFullViewer::setBottomWheelValue(const float value)
581
this->bottomWheelVal = value;
582
// Wheel may not be constructed yet, but we need to be robust, as
583
// set*WheelValue() is used from subclasses.
584
if (this->bottomWheel) {
585
SoQtFullViewerP::setThumbWheelValue(this->bottomWheel, value);
590
Get current value of the bottom thumbwheel.
592
\sa bottomWheelMotion()
595
SoQtFullViewer::getBottomWheelValue(void) const
597
return this->bottomWheelVal;
601
Called when the user start to drag the thumbwheel in the right
602
frame. Override this method in subclassed viewers to provide your
603
own functionality on the thumbwheel.
605
\sa rightWheelMotion(), rightWheelFinish()
606
\sa leftWheelStart(), bottomWheelStart()
609
SoQtFullViewer::rightWheelStart(void)
611
this->interactiveCountInc();
615
Called repeatedly as the user drags the thumbwheel in the right
616
frame. Override this method in subclassed viewers to provide your
617
own functionality on the thumbwheel.
619
\sa rightWheelStart(), rightWheelFinish()
620
\sa leftWheelStart(), bottomWheelStart()
623
SoQtFullViewer::rightWheelMotion(float value)
625
this->rightWheelVal = value;
629
Called as the user let go of the thumbwheel in the right frame
630
after a drag operation. Override this method in subclassed viewers
631
to provide your own functionality on the thumbwheel.
633
\sa rightWheelStart(), rightWheelMotion()
634
\sa leftWheelStart(), bottomWheelStart()
637
SoQtFullViewer::rightWheelFinish(void)
639
this->interactiveCountDec();
643
Set a new value for the right thumbwheel.
646
SoQtFullViewer::setRightWheelValue(const float value)
648
this->rightWheelVal = value;
649
// Wheel may not be constructed yet, but we need to be robust, as
650
// set*WheelValue() is used from subclasses.
651
if (this->rightWheel) {
652
SoQtFullViewerP::setThumbWheelValue(this->rightWheel, value);
657
Get current value of the right thumbwheel.
659
\sa rightWheelMotion()
662
SoQtFullViewer::getRightWheelValue(void) const
664
return this->rightWheelVal;
667
// *************************************************************************
670
This method returns the native widget for the label below the left
675
SoQtFullViewer::getLeftWheelLabelWidget(void) const
677
return this->leftWheelLabel;
681
This method returns the native widget for the label below the right thumb
685
SoQtFullViewer::getRightWheelLabelWidget(void) const
687
return this->rightWheelLabel;
691
This method returns the native widget for the label beside the
695
SoQtFullViewer::getBottomWheelLabelWidget(void) const
697
return this->bottomWheelLabel;
700
// ************************************************************************
703
Set title of popup menu.
706
SoQtFullViewer::setPopupMenuString(const char * name)
708
PRIVATE(this)->popupmenutitle = name;
709
if (this->prefmenu) { this->prefmenu->setMenuTitle(SoGuiFullViewerP::ROOT_MENU, name); }
713
// Documented in superclass.
715
SoQtFullViewer::processSoEvent(const SoEvent * const ev)
717
// We're in "interact" mode (ie *not* the camera modification mode),
718
// so don't handle the event here. It should either be forwarded to
719
// the scenegraph, or caught by SoQtViewer::processSoEvent() if
720
// it's an ESC press (to switch modes).
721
if (!this->isViewing()) { return inherited::processSoEvent(ev); }
723
// Note: with the original SGI InventorXt, the popup menu is also
724
// activated by RMB clicks in non-viewing mode. We want to allow RMB
725
// clicks to pass through to the scenegraph in non-viewing mode, so
726
// we don't copy that behavior.
728
if (ev->getTypeId().isDerivedFrom(SoMouseButtonEvent::getClassTypeId())) {
729
SoMouseButtonEvent * const e = (SoMouseButtonEvent *) ev;
730
if ((e->getButton() == SoMouseButtonEvent::BUTTON2)) {
731
if (this->isPopupMenuEnabled()) {
732
if (e->getState() == SoButtonEvent::DOWN) {
733
this->openPopupMenu(e->getPosition());
735
// Steal all RMB-events if the viewer uses the popup-menu.
741
return inherited::processSoEvent(ev);
744
// *************************************************************************
746
// FIXME: get rid of this hack and make this file truly
747
// "generic". 20020109 mortene.
748
#ifndef __COIN_SOWIN__
750
// *************************************************************************
752
// Doc in superclass.
754
SoQtFullViewer::setComponentCursor(const SoQtCursor & cursor)
756
// Overridden to apply the new cursor only for the rendering canvas
757
// widget. Otherwise, the default SoQtComponent
758
// setComponentCursor() method will set the cursor for the top-most
759
// parent widget, which makes it affect all sub-widgets, like the
760
// decorations stuff.
762
SoQtComponent::setWidgetCursor(this->getGLWidget(), cursor);
765
// *************************************************************************
767
#endif // ! __COIN_SOWIN__
769
// ************************************************************************
771
#ifndef DOXYGEN_SKIP_THIS
773
SoGuiFullViewerP::SoGuiFullViewerP(SoQtFullViewer * owner)
778
SoGuiFullViewerP::~SoGuiFullViewerP()
783
SoGuiFullViewerP::setupStandardPopupMenu(void)
785
SoQtPopupMenu * menu = SoQtPopupMenu::createInstance();
787
menu->newMenu("rootmenu", ROOT_MENU);
788
// FIXME: none of the So*-toolkits so far uses the rootmenu title to
789
// set up a title string at the top of the root popupmenu. 20010810 mortene.
790
menu->setMenuTitle(ROOT_MENU, this->popupmenutitle.getString());
792
#if 0 // OBSOLETED: this looks ugly and confusing for the user. 20010810 mortene.
793
// Simple hack for a common / generic way of setting up a title for
795
menu->newMenuItem("rootmenutitle", ROOT_MENU_TITLE);
796
menu->setMenuItemTitle(ROOT_MENU_TITLE, this->popupmenutitle.getString());
797
menu->addMenuItem(ROOT_MENU, ROOT_MENU_TITLE);
798
menu->setMenuItemEnabled(ROOT_MENU_TITLE, FALSE);
799
menu->addSeparator(ROOT_MENU);
802
menu->newMenu("functionsmenu", FUNCTIONS_MENU);
803
menu->setMenuTitle(FUNCTIONS_MENU, _("Functions"));
804
menu->newMenu("drawstylesmenu", DRAWSTYLES_MENU);
805
menu->setMenuTitle(DRAWSTYLES_MENU, _("Draw Styles"));
806
menu->newMenu("stereomenu", STEREO_MENU);
807
menu->setMenuTitle(STEREO_MENU, _("Stereo Viewing"));
808
menu->newMenuItem("examining", EXAMINING_ITEM);
809
menu->setMenuItemTitle(EXAMINING_ITEM, _("Viewing"));
810
menu->newMenuItem("decoration", DECORATION_ITEM);
811
menu->setMenuItemTitle(DECORATION_ITEM, _("Decorations"));
812
menu->newMenuItem("headlight", HEADLIGHT_ITEM);
813
menu->setMenuItemTitle(HEADLIGHT_ITEM, _("Headlight"));
814
menu->newMenuItem("fullscreen", FULLSCREEN_ITEM);
815
menu->setMenuItemTitle(FULLSCREEN_ITEM, _("Fullscreen"));
817
menu->addMenu(ROOT_MENU, FUNCTIONS_MENU);
818
menu->addMenu(ROOT_MENU, DRAWSTYLES_MENU);
819
menu->addMenu(ROOT_MENU, STEREO_MENU);
820
menu->addMenuItem(ROOT_MENU, EXAMINING_ITEM);
821
menu->addMenuItem(ROOT_MENU, DECORATION_ITEM);
822
menu->addMenuItem(ROOT_MENU, HEADLIGHT_ITEM);
823
menu->addMenuItem(ROOT_MENU, FULLSCREEN_ITEM);
825
menu->newMenuItem("home", HOME_ITEM);
826
menu->setMenuItemTitle(HOME_ITEM, _("Home"));
827
menu->newMenuItem("set_home", SET_HOME_ITEM);
828
menu->setMenuItemTitle(SET_HOME_ITEM, _("Set Home"));
829
menu->newMenuItem("view_all", VIEW_ALL_ITEM);
830
menu->setMenuItemTitle(VIEW_ALL_ITEM, _("View All"));
831
menu->newMenuItem("seek", SEEK_ITEM);
832
menu->setMenuItemTitle(SEEK_ITEM, _("Seek"));
834
menu->addMenuItem(FUNCTIONS_MENU, HOME_ITEM);
835
menu->addMenuItem(FUNCTIONS_MENU, SET_HOME_ITEM);
836
menu->addMenuItem(FUNCTIONS_MENU, VIEW_ALL_ITEM);
837
menu->addMenuItem(FUNCTIONS_MENU, SEEK_ITEM);
839
menu->newMenu("drawstylesstill", DRAWSTYLES_STILL_MENU);
840
menu->setMenuTitle(DRAWSTYLES_STILL_MENU, _("Still Drawstyle"));
842
menu->newMenuItem("as_is", AS_IS_ITEM);
843
menu->setMenuItemTitle(AS_IS_ITEM, _("as is"));
844
menu->newMenuItem("hidden_line", HIDDEN_LINE_ITEM);
845
menu->setMenuItemTitle(HIDDEN_LINE_ITEM, _("hidden line"));
846
menu->newMenuItem("wireframe_overlay", WIREFRAME_OVERLAY_ITEM);
847
menu->setMenuItemTitle(WIREFRAME_OVERLAY_ITEM, _("wireframe overlay"));
848
menu->newMenuItem("no_textures", NO_TEXTURE_ITEM);
849
menu->setMenuItemTitle(NO_TEXTURE_ITEM, _("no texture"));
850
menu->newMenuItem("low_resolution", LOW_RESOLUTION_ITEM);
851
menu->setMenuItemTitle(LOW_RESOLUTION_ITEM, _("low resolution"));
852
menu->newMenuItem("wireframe", WIREFRAME_ITEM);
853
menu->setMenuItemTitle(WIREFRAME_ITEM, _("wireframe"));
854
menu->newMenuItem("points", POINTS_ITEM);
855
menu->setMenuItemTitle(POINTS_ITEM, _("points"));
856
menu->newMenuItem("bounding_box", BOUNDING_BOX_ITEM);
857
menu->setMenuItemTitle(BOUNDING_BOX_ITEM, _("bounding box (no depth)"));
859
menu->newRadioGroup(STILL_GROUP);
860
menu->addRadioGroupItem(STILL_GROUP, AS_IS_ITEM);
861
menu->addRadioGroupItem(STILL_GROUP, HIDDEN_LINE_ITEM);
862
menu->addRadioGroupItem(STILL_GROUP, WIREFRAME_OVERLAY_ITEM);
863
menu->addRadioGroupItem(STILL_GROUP, NO_TEXTURE_ITEM);
864
menu->addRadioGroupItem(STILL_GROUP, LOW_RESOLUTION_ITEM);
865
menu->addRadioGroupItem(STILL_GROUP, WIREFRAME_ITEM);
866
menu->addRadioGroupItem(STILL_GROUP, POINTS_ITEM);
867
menu->addRadioGroupItem(STILL_GROUP, BOUNDING_BOX_ITEM);
869
menu->addMenuItem(DRAWSTYLES_STILL_MENU, AS_IS_ITEM);
870
menu->addMenuItem(DRAWSTYLES_STILL_MENU, HIDDEN_LINE_ITEM);
871
menu->addMenuItem(DRAWSTYLES_STILL_MENU, WIREFRAME_OVERLAY_ITEM);
872
menu->addMenuItem(DRAWSTYLES_STILL_MENU, NO_TEXTURE_ITEM);
873
menu->addMenuItem(DRAWSTYLES_STILL_MENU, LOW_RESOLUTION_ITEM);
874
menu->addMenuItem(DRAWSTYLES_STILL_MENU, WIREFRAME_ITEM);
875
menu->addMenuItem(DRAWSTYLES_STILL_MENU, POINTS_ITEM);
876
menu->addMenuItem(DRAWSTYLES_STILL_MENU, BOUNDING_BOX_ITEM);
878
menu->newMenu("drawstylesanimation", DRAWSTYLES_ANIMATING_MENU);
879
menu->setMenuTitle(DRAWSTYLES_ANIMATING_MENU, _("Animating Drawstyle"));
881
menu->newMenuItem("move_same_as_still", MOVE_SAME_AS_STILL_ITEM);
882
menu->setMenuItemTitle(MOVE_SAME_AS_STILL_ITEM, _("same as still"));
883
menu->newMenuItem("move_no_texture", MOVE_NO_TEXTURE_ITEM);
884
menu->setMenuItemTitle(MOVE_NO_TEXTURE_ITEM, _("no texture"));
885
menu->newMenuItem("move_low_res", MOVE_LOW_RES_ITEM);
886
menu->setMenuItemTitle(MOVE_LOW_RES_ITEM, _("low resolution"));
887
menu->newMenuItem("move_wireframe", MOVE_WIREFRAME_ITEM);
888
menu->setMenuItemTitle(MOVE_WIREFRAME_ITEM, _("wireframe"));
889
menu->newMenuItem("move_low_res_wireframe", MOVE_LOW_RES_WIREFRAME_ITEM);
890
menu->setMenuItemTitle(MOVE_LOW_RES_WIREFRAME_ITEM,
891
_("low res wireframe (no depth)"));
892
menu->newMenuItem("move_points", MOVE_POINTS_ITEM);
893
menu->setMenuItemTitle(MOVE_POINTS_ITEM, _("points"));
894
menu->newMenuItem("move_low_res_points", MOVE_LOW_RES_POINTS_ITEM);
895
menu->setMenuItemTitle(MOVE_LOW_RES_POINTS_ITEM,
896
_("low res points (no depth)"));
897
menu->newMenuItem("move_bounding_box", MOVE_BOUNDING_BOX_ITEM);
898
menu->setMenuItemTitle(MOVE_BOUNDING_BOX_ITEM, _("bounding box (no depth)"));
900
menu->newRadioGroup(MOVE_GROUP);
901
menu->addRadioGroupItem(MOVE_GROUP, MOVE_SAME_AS_STILL_ITEM);
902
menu->addRadioGroupItem(MOVE_GROUP, MOVE_NO_TEXTURE_ITEM);
903
menu->addRadioGroupItem(MOVE_GROUP, MOVE_LOW_RES_ITEM);
904
menu->addRadioGroupItem(MOVE_GROUP, MOVE_WIREFRAME_ITEM);
905
menu->addRadioGroupItem(MOVE_GROUP, MOVE_LOW_RES_WIREFRAME_ITEM);
906
menu->addRadioGroupItem(MOVE_GROUP, MOVE_POINTS_ITEM);
907
menu->addRadioGroupItem(MOVE_GROUP, MOVE_LOW_RES_POINTS_ITEM);
908
menu->addRadioGroupItem(MOVE_GROUP, MOVE_BOUNDING_BOX_ITEM);
910
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_SAME_AS_STILL_ITEM);
911
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_NO_TEXTURE_ITEM);
912
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_LOW_RES_ITEM);
913
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_WIREFRAME_ITEM);
914
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_LOW_RES_WIREFRAME_ITEM);
915
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_POINTS_ITEM);
916
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_LOW_RES_POINTS_ITEM);
917
menu->addMenuItem(DRAWSTYLES_ANIMATING_MENU, MOVE_BOUNDING_BOX_ITEM);
919
menu->newMenu("transparencytype", TRANSPARENCY_TYPE_MENU);
920
menu->setMenuTitle(TRANSPARENCY_TYPE_MENU, _("Transparency Type"));
921
menu->newRadioGroup(TRANSPARENCY_GROUP);
923
{ // Fill in menu items in radiomenu with transparency selections.
925
struct menutransparencyitem {
926
const char * name, * title;
930
struct menutransparencyitem items[] = {
932
{ "none", _("none"), NONE_TRANSPARENCY_ITEM },
934
{ "screen_door", _("screen door"), SCREEN_DOOR_TRANSPARENCY_ITEM },
935
{ "add", _("add"), ADD_TRANSPARENCY_ITEM },
936
{ "delayed_add", _("delayed add"), DELAYED_ADD_TRANSPARENCY_ITEM },
937
{ "sorted_object_add", _("sorted object add"), SORTED_OBJECT_ADD_TRANSPARENCY_ITEM },
938
{ "blend", _("blend"), BLEND_TRANSPARENCY_ITEM },
939
{ "delayed_blend", _("delayed blend"), DELAYED_BLEND_TRANSPARENCY_ITEM },
940
{ "sorted_object_blend", _("sorted object blend"), SORTED_OBJECT_BLEND_TRANSPARENCY_ITEM }
941
#ifdef __COIN__ // Coin extensions
943
{ "sorted_object_sorted_triangle_add", _("sorted object sorted triangle add"), SORTED_OBJECT_SORTED_TRIANGLE_ADD_TRANSPARENCY_ITEM },
944
{ "sorted_object_sorted_triangle_blend", _("sorted object sorted triangle blend"), SORTED_OBJECT_SORTED_TRIANGLE_BLEND_TRANSPARENCY_ITEM }
946
#ifdef HAVE_SORTED_LAYERS_BLEND
947
, { "sorted_layers_blend", _("sorted layers blend"), SORTED_LAYERS_BLEND_ITEM }
948
#endif // HAVE_SORTED_LAYERS_BLEND
951
int nritems = sizeof(items) / sizeof(struct menutransparencyitem);
952
for (int i = 0; i < nritems; i++) {
953
menu->newMenuItem(items[i].name, items[i].id);
954
menu->setMenuItemTitle(items[i].id, items[i].title);
955
menu->addRadioGroupItem(TRANSPARENCY_GROUP, items[i].id);
956
menu->addMenuItem(TRANSPARENCY_TYPE_MENU, items[i].id);
960
menu->newMenuItem("stereooff", STEREO_OFF_ITEM);
961
menu->newMenuItem("stereoredcyan", STEREO_ANAGLYPH_ITEM);
962
menu->newMenuItem("stereoquadbuffer", STEREO_QUADBUFFER_ITEM);
963
menu->setMenuItemTitle(STEREO_OFF_ITEM, _("Off"));
964
menu->setMenuItemTitle(STEREO_ANAGLYPH_ITEM, _("Red/Cyan Anaglyph"));
965
menu->setMenuItemTitle(STEREO_QUADBUFFER_ITEM, _("Quad buffer"));
967
menu->newMenuItem("stereointerleavedrows", STEREO_INTERLEAVED_ROWS_ITEM);
968
menu->setMenuItemTitle(STEREO_INTERLEAVED_ROWS_ITEM, _("Interleaved Rows"));
969
menu->newMenuItem("stereointerleavedcolumns", STEREO_INTERLEAVED_COLUMNS_ITEM);
970
menu->setMenuItemTitle(STEREO_INTERLEAVED_COLUMNS_ITEM, _("Interleaved Columns"));
972
menu->newRadioGroup(STEREO_GROUP);
973
menu->addRadioGroupItem(STEREO_GROUP, STEREO_OFF_ITEM);
974
menu->addRadioGroupItem(STEREO_GROUP, STEREO_ANAGLYPH_ITEM);
975
menu->addRadioGroupItem(STEREO_GROUP, STEREO_QUADBUFFER_ITEM);
976
menu->addRadioGroupItem(STEREO_GROUP, STEREO_INTERLEAVED_ROWS_ITEM);
977
menu->addRadioGroupItem(STEREO_GROUP, STEREO_INTERLEAVED_COLUMNS_ITEM);
979
menu->addMenuItem(STEREO_MENU, STEREO_OFF_ITEM);
980
menu->addMenuItem(STEREO_MENU, STEREO_ANAGLYPH_ITEM);
981
menu->addMenuItem(STEREO_MENU, STEREO_QUADBUFFER_ITEM);
982
menu->addMenuItem(STEREO_MENU, STEREO_INTERLEAVED_ROWS_ITEM);
983
menu->addMenuItem(STEREO_MENU, STEREO_INTERLEAVED_COLUMNS_ITEM);
985
menu->newMenu("renderbuffertype", RENDER_BUFFER_TYPE_MENU);
986
menu->setMenuTitle(RENDER_BUFFER_TYPE_MENU, _("Render Buffer Type"));
988
menu->newMenuItem("single_buffer", SINGLE_BUFFER_ITEM);
989
menu->setMenuItemTitle(SINGLE_BUFFER_ITEM, _("single"));
990
menu->newMenuItem("double_buffer", DOUBLE_BUFFER_ITEM);
991
menu->setMenuItemTitle(DOUBLE_BUFFER_ITEM, _("double"));
992
menu->newMenuItem("interactive_buffer", INTERACTIVE_BUFFER_ITEM);
993
menu->setMenuItemTitle(INTERACTIVE_BUFFER_ITEM, _("interactive"));
995
menu->newRadioGroup(BUFFER_GROUP);
996
menu->addRadioGroupItem(BUFFER_GROUP, SINGLE_BUFFER_ITEM);
997
menu->addRadioGroupItem(BUFFER_GROUP, DOUBLE_BUFFER_ITEM);
998
menu->addRadioGroupItem(BUFFER_GROUP, INTERACTIVE_BUFFER_ITEM);
1000
menu->addMenuItem(RENDER_BUFFER_TYPE_MENU, SINGLE_BUFFER_ITEM);
1001
menu->addMenuItem(RENDER_BUFFER_TYPE_MENU, DOUBLE_BUFFER_ITEM);
1002
menu->addMenuItem(RENDER_BUFFER_TYPE_MENU, INTERACTIVE_BUFFER_ITEM);
1004
menu->addMenu(DRAWSTYLES_MENU, DRAWSTYLES_STILL_MENU);
1005
menu->addMenu(DRAWSTYLES_MENU, DRAWSTYLES_ANIMATING_MENU);
1006
menu->addMenu(DRAWSTYLES_MENU, TRANSPARENCY_TYPE_MENU);
1007
menu->addMenu(DRAWSTYLES_MENU, RENDER_BUFFER_TYPE_MENU);
1010
toggle = menu->newRadioGroup();
1011
menu->addRadioGroupItem(toggle, EXAMINING_ITEM);
1012
toggle = menu->newRadioGroup();
1013
menu->addRadioGroupItem(toggle, DECORATION_ITEM);
1014
toggle = menu->newRadioGroup();
1015
menu->addRadioGroupItem(toggle, HEADLIGHT_ITEM);
1016
toggle = menu->newRadioGroup();
1017
menu->addRadioGroupItem(toggle, FULLSCREEN_ITEM);
1019
menu->addMenuSelectionCallback(SoGuiFullViewerP::menuSelectionCallback,
1022
PUBLIC(this)->prefmenu = menu;
1026
// ************************************************************************
1029
SoGuiFullViewerP::prepareMenu(SoQtPopupMenu * menu)
1031
//// Misc. //////////////////////////////////////////////////////////
1032
menu->setMenuItemMarked(DECORATION_ITEM, PUBLIC(this)->isDecoration());
1033
menu->setMenuItemMarked(EXAMINING_ITEM, PUBLIC(this)->isViewing());
1034
menu->setMenuItemMarked(HEADLIGHT_ITEM, PUBLIC(this)->isHeadlight());
1035
menu->setMenuItemMarked(FULLSCREEN_ITEM, PUBLIC(this)->isFullScreen());
1037
//// Basic drawstyles. //////////////////////////////////////////////
1038
this->setDrawStyleMenuActivation(SoQtFullViewer::STILL,
1039
PUBLIC(this)->getDrawStyle(SoQtFullViewer::STILL));
1040
this->setDrawStyleMenuActivation(SoQtFullViewer::INTERACTIVE,
1041
PUBLIC(this)->getDrawStyle(SoQtFullViewer::INTERACTIVE));
1043
//// Transparency setting. //////////////////////////////////////////
1044
switch (PUBLIC(this)->getTransparencyType()) {
1045
case SoGLRenderAction::SCREEN_DOOR:
1046
menu->setMenuItemMarked(SCREEN_DOOR_TRANSPARENCY_ITEM, TRUE);
1048
case SoGLRenderAction::ADD:
1049
menu->setMenuItemMarked(ADD_TRANSPARENCY_ITEM, TRUE);
1051
case SoGLRenderAction::DELAYED_ADD:
1052
menu->setMenuItemMarked(DELAYED_ADD_TRANSPARENCY_ITEM, TRUE);
1054
case SoGLRenderAction::SORTED_OBJECT_ADD:
1055
menu->setMenuItemMarked(SORTED_OBJECT_ADD_TRANSPARENCY_ITEM, TRUE);
1057
case SoGLRenderAction::BLEND:
1058
menu->setMenuItemMarked(BLEND_TRANSPARENCY_ITEM, TRUE);
1060
case SoGLRenderAction::DELAYED_BLEND:
1061
menu->setMenuItemMarked(DELAYED_BLEND_TRANSPARENCY_ITEM, TRUE);
1063
case SoGLRenderAction::SORTED_OBJECT_BLEND:
1064
menu->setMenuItemMarked(SORTED_OBJECT_BLEND_TRANSPARENCY_ITEM, TRUE);
1066
#ifdef __COIN__ // Coin extensions
1067
case SoGLRenderAction::NONE:
1068
menu->setMenuItemMarked(NONE_TRANSPARENCY_ITEM, TRUE);
1070
case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD:
1071
menu->setMenuItemMarked(SORTED_OBJECT_SORTED_TRIANGLE_ADD_TRANSPARENCY_ITEM, TRUE);
1073
case SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND:
1074
menu->setMenuItemMarked(SORTED_OBJECT_SORTED_TRIANGLE_BLEND_TRANSPARENCY_ITEM, TRUE);
1077
#ifdef HAVE_SORTED_LAYERS_BLEND
1078
case SoGLRenderAction::SORTED_LAYERS_BLEND:
1079
menu->setMenuItemMarked(SORTED_LAYERS_BLEND_ITEM, TRUE);
1081
#endif // HAVE_SORTED_LAYERS_BLEND
1084
SoDebugError::postInfo("SoGuiFullViewerP::prepareMenu",
1085
"Unknown transparency type");
1086
#endif // SOQT_DEBUG
1090
//// Stereo viewing. ////////////////////////////////////////////////
1092
const SoQtViewer::StereoType type = PUBLIC(this)->getStereoType();
1094
case SoQtViewer::STEREO_NONE:
1095
menu->setMenuItemMarked(STEREO_OFF_ITEM, TRUE);
1097
case SoQtViewer::STEREO_ANAGLYPH:
1098
menu->setMenuItemMarked(STEREO_ANAGLYPH_ITEM, TRUE);
1100
case SoQtViewer::STEREO_QUADBUFFER:
1101
menu->setMenuItemMarked(STEREO_QUADBUFFER_ITEM, TRUE);
1103
case SoQtViewer::STEREO_INTERLEAVED_ROWS:
1104
menu->setMenuItemMarked(STEREO_INTERLEAVED_ROWS_ITEM, TRUE);
1106
case SoQtViewer::STEREO_INTERLEAVED_COLUMNS:
1107
menu->setMenuItemMarked(STEREO_INTERLEAVED_COLUMNS_ITEM, TRUE);
1110
assert(FALSE); break;
1113
//// GL canvas settings. ////////////////////////////////////////////
1114
switch (PUBLIC(this)->getBufferingType()) {
1115
case SoQtViewer::BUFFER_SINGLE:
1116
menu->setMenuItemMarked(SINGLE_BUFFER_ITEM, TRUE);
1118
case SoQtViewer::BUFFER_DOUBLE:
1119
menu->setMenuItemMarked(DOUBLE_BUFFER_ITEM, TRUE);
1121
case SoQtViewer::BUFFER_INTERACTIVE:
1122
menu->setMenuItemMarked(INTERACTIVE_BUFFER_ITEM, TRUE);
1126
SoDebugError::postInfo("SoGuiFullViewerP::prepareMenu",
1127
"Unknown buffer type");
1128
#endif // SOQT_DEBUG
1133
// ************************************************************************
1136
SoGuiFullViewerP::menuSelection(int menuitemid)
1140
switch (menuitemid) {
1142
// means no item was selected
1144
SoDebugError::postInfo("SoGuiFullViewerP::menuSelection",
1145
"-1 not appropriate on callback usage");
1146
#endif // SOQT_DEBUG
1149
case EXAMINING_ITEM:
1150
PUBLIC(this)->setViewing(PUBLIC(this)->isViewing() ? FALSE : TRUE);
1152
case DECORATION_ITEM:
1153
PUBLIC(this)->setDecoration(PUBLIC(this)->isDecoration() ? FALSE : TRUE);
1155
case HEADLIGHT_ITEM:
1156
PUBLIC(this)->setHeadlight(PUBLIC(this)->isHeadlight() ? FALSE : TRUE);
1158
case FULLSCREEN_ITEM:
1159
(void)PUBLIC(this)->setFullScreen(PUBLIC(this)->isFullScreen() ? FALSE : TRUE);
1163
PUBLIC(this)->resetToHomePosition();
1166
PUBLIC(this)->saveHomePosition();
1169
PUBLIC(this)->viewAll();
1172
((SoQtFullViewerP *)this)->seekbuttonClicked();
1176
case HIDDEN_LINE_ITEM:
1177
case WIREFRAME_OVERLAY_ITEM:
1178
case NO_TEXTURE_ITEM:
1179
case LOW_RESOLUTION_ITEM:
1180
case WIREFRAME_ITEM:
1182
case BOUNDING_BOX_ITEM:
1183
this->drawstyleActivated(menuitemid);
1186
case MOVE_SAME_AS_STILL_ITEM:
1187
case MOVE_NO_TEXTURE_ITEM:
1188
case MOVE_LOW_RES_ITEM:
1189
case MOVE_WIREFRAME_ITEM:
1190
case MOVE_LOW_RES_WIREFRAME_ITEM:
1191
case MOVE_POINTS_ITEM:
1192
case MOVE_LOW_RES_POINTS_ITEM:
1193
case MOVE_BOUNDING_BOX_ITEM:
1194
this->drawstyleActivated(menuitemid);
1197
case SCREEN_DOOR_TRANSPARENCY_ITEM:
1198
case ADD_TRANSPARENCY_ITEM:
1199
case DELAYED_ADD_TRANSPARENCY_ITEM:
1200
case SORTED_OBJECT_ADD_TRANSPARENCY_ITEM:
1201
case BLEND_TRANSPARENCY_ITEM:
1202
case DELAYED_BLEND_TRANSPARENCY_ITEM:
1203
case SORTED_OBJECT_BLEND_TRANSPARENCY_ITEM:
1204
case SORTED_OBJECT_SORTED_TRIANGLE_ADD_TRANSPARENCY_ITEM:
1205
case SORTED_OBJECT_SORTED_TRIANGLE_BLEND_TRANSPARENCY_ITEM:
1206
case NONE_TRANSPARENCY_ITEM:
1207
case SORTED_LAYERS_BLEND_ITEM: // define test is not needed. This enum is always defined
1208
this->drawstyleActivated(menuitemid);
1209
PUBLIC(this)->scheduleRedraw();
1212
case SINGLE_BUFFER_ITEM:
1213
case DOUBLE_BUFFER_ITEM:
1214
case INTERACTIVE_BUFFER_ITEM:
1215
this->drawstyleActivated(menuitemid);
1218
case STEREO_OFF_ITEM:
1219
ok = PUBLIC(this)->setStereoType(SoQtViewer::STEREO_NONE);
1222
case STEREO_ANAGLYPH_ITEM:
1223
ok = PUBLIC(this)->setStereoType(SoQtViewer::STEREO_ANAGLYPH);
1224
assert(ok && "anaglyph stereo should always be possible");
1226
case STEREO_QUADBUFFER_ITEM:
1227
ok = PUBLIC(this)->setStereoType(SoQtViewer::STEREO_QUADBUFFER);
1228
if (!ok) { PUBLIC(this)->setStereoType(SoQtViewer::STEREO_NONE); }
1230
case STEREO_INTERLEAVED_ROWS_ITEM:
1231
ok = PUBLIC(this)->setStereoType(SoQtViewer::STEREO_INTERLEAVED_ROWS);
1232
if (!ok) { PUBLIC(this)->setStereoType(SoQtViewer::STEREO_NONE); }
1234
case STEREO_INTERLEAVED_COLUMNS_ITEM:
1235
ok = PUBLIC(this)->setStereoType(SoQtViewer::STEREO_INTERLEAVED_COLUMNS);
1236
if (!ok) { PUBLIC(this)->setStereoType(SoQtViewer::STEREO_NONE); }
1240
SoDebugError::postInfo("SoGuiFullViewerP::menuSelection",
1241
"popup menu handling for item %d is not implemented",
1248
// ************************************************************************
1251
SoGuiFullViewerP::menuSelectionCallback(int menuitemid,
1254
SoGuiFullViewerP * viewer = (SoGuiFullViewerP *) userdata;
1255
viewer->menuSelection(menuitemid);
1258
// ************************************************************************
1261
SoGuiFullViewerP::setDrawStyleMenuActivation(SoQtViewer::DrawType type,
1262
SoQtViewer::DrawStyle value)
1264
assert(PUBLIC(this)->prefmenu != NULL);
1267
case SoQtViewer::STILL:
1269
case SoQtViewer::VIEW_AS_IS:
1270
PUBLIC(this)->prefmenu->setMenuItemMarked(AS_IS_ITEM, TRUE);
1272
case SoQtViewer::VIEW_HIDDEN_LINE:
1273
PUBLIC(this)->prefmenu->setMenuItemMarked(HIDDEN_LINE_ITEM, TRUE);
1275
case SoQtViewer::VIEW_WIREFRAME_OVERLAY:
1276
PUBLIC(this)->prefmenu->setMenuItemMarked(WIREFRAME_OVERLAY_ITEM, TRUE);
1278
case SoQtViewer::VIEW_NO_TEXTURE:
1279
PUBLIC(this)->prefmenu->setMenuItemMarked(NO_TEXTURE_ITEM, TRUE);
1281
case SoQtViewer::VIEW_LOW_COMPLEXITY:
1282
PUBLIC(this)->prefmenu->setMenuItemMarked(LOW_RESOLUTION_ITEM, TRUE);
1284
case SoQtViewer::VIEW_LOW_RES_LINE:
1286
SoDebugError::postWarning("SoQtFullViewer::setDrawStyleMenuActivation",
1287
"Use VIEW_LINE, not VIEW_LOW_RES_LINE for the STILL drawstyle.");
1289
case SoQtViewer::VIEW_LINE:
1290
PUBLIC(this)->prefmenu->setMenuItemMarked(WIREFRAME_ITEM, TRUE);
1292
case SoQtViewer::VIEW_LOW_RES_POINT:
1294
SoDebugError::postWarning("SoQtFullViewer::setDrawStyleMenuActivation",
1295
"Use VIEW_POINT, not VIEW_LOW_RES_POINT for the STILL drawstyle.");
1297
case SoQtViewer::VIEW_POINT:
1298
PUBLIC(this)->prefmenu->setMenuItemMarked(POINTS_ITEM, TRUE);
1300
case SoQtViewer::VIEW_BBOX:
1301
PUBLIC(this)->prefmenu->setMenuItemMarked(BOUNDING_BOX_ITEM, TRUE);
1305
SoDebugError::postWarning("SoQtFullViewer::setDrawStyleMenuActivation",
1306
"Unsupporter still-drawstyle");
1312
case SoQtViewer::INTERACTIVE:
1314
case SoQtViewer::VIEW_SAME_AS_STILL:
1315
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_SAME_AS_STILL_ITEM, TRUE);
1317
case SoQtViewer::VIEW_NO_TEXTURE:
1318
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_NO_TEXTURE_ITEM, TRUE);
1320
case SoQtViewer::VIEW_LOW_COMPLEXITY:
1321
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_LOW_RES_ITEM, TRUE);
1323
case SoQtViewer::VIEW_LINE:
1324
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_WIREFRAME_ITEM, TRUE);
1326
case SoQtViewer::VIEW_LOW_RES_LINE:
1327
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_LOW_RES_WIREFRAME_ITEM, TRUE);
1329
case SoQtViewer::VIEW_POINT:
1330
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_POINTS_ITEM, TRUE);
1332
case SoQtViewer::VIEW_LOW_RES_POINT:
1333
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_LOW_RES_POINTS_ITEM, TRUE);
1335
case SoQtViewer::VIEW_BBOX:
1336
PUBLIC(this)->prefmenu->setMenuItemMarked(MOVE_BOUNDING_BOX_ITEM, TRUE);
1340
SoDebugError::postWarning("SoQtFullViewer::setDrawStyleMenuActivation",
1341
"Unsupporter interactive drawstyle");
1349
SoDebugError::postWarning("SoQtFullViewer::setDrawStyleMenuActivation",
1350
"Unsupporter drawstyle type");
1356
// ************************************************************************
1359
SoGuiFullViewerP::drawstyleActivated(int menuitemid)
1361
switch (menuitemid) {
1362
case SINGLE_BUFFER_ITEM:
1363
PUBLIC(this)->setBufferingType(SoQtViewer::BUFFER_SINGLE);
1365
case DOUBLE_BUFFER_ITEM:
1366
PUBLIC(this)->setBufferingType(SoQtViewer::BUFFER_DOUBLE);
1368
case INTERACTIVE_BUFFER_ITEM:
1369
PUBLIC(this)->setBufferingType(SoQtViewer::BUFFER_INTERACTIVE);
1375
// FIXME: should perhaps override transparency type to be screendoor
1376
// if we detect that the OpenGL canvas has 0 alpha bits available?
1377
// 20030626 mortene.
1378
switch (menuitemid) {
1379
case SCREEN_DOOR_TRANSPARENCY_ITEM:
1380
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SCREEN_DOOR);
1382
case ADD_TRANSPARENCY_ITEM:
1383
PUBLIC(this)->setTransparencyType(SoGLRenderAction::ADD);
1385
case DELAYED_ADD_TRANSPARENCY_ITEM:
1386
PUBLIC(this)->setTransparencyType(SoGLRenderAction::DELAYED_ADD);
1388
case SORTED_OBJECT_ADD_TRANSPARENCY_ITEM:
1389
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_ADD);
1391
case BLEND_TRANSPARENCY_ITEM:
1392
PUBLIC(this)->setTransparencyType(SoGLRenderAction::BLEND);
1394
case DELAYED_BLEND_TRANSPARENCY_ITEM:
1395
PUBLIC(this)->setTransparencyType(SoGLRenderAction::DELAYED_BLEND);
1397
case SORTED_OBJECT_BLEND_TRANSPARENCY_ITEM:
1398
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_BLEND);
1400
#ifdef __COIN__ // Coin extensions
1401
case NONE_TRANSPARENCY_ITEM:
1402
PUBLIC(this)->setTransparencyType(SoGLRenderAction::NONE);
1404
case SORTED_OBJECT_SORTED_TRIANGLE_ADD_TRANSPARENCY_ITEM:
1405
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_ADD);
1407
case SORTED_OBJECT_SORTED_TRIANGLE_BLEND_TRANSPARENCY_ITEM:
1408
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SORTED_OBJECT_SORTED_TRIANGLE_BLEND);
1411
#ifdef HAVE_SORTED_LAYERS_BLEND
1412
case SORTED_LAYERS_BLEND_ITEM:
1413
PUBLIC(this)->setTransparencyType(SoGLRenderAction::SORTED_LAYERS_BLEND);
1415
#endif // HAVE_SORTED_LAYERS_BLEND
1417
// some other menu item, just continue
1421
SoQtViewer::DrawStyle val = SoQtViewer::VIEW_AS_IS;
1422
switch (menuitemid) {
1424
val = SoQtViewer::VIEW_AS_IS;
1426
case HIDDEN_LINE_ITEM:
1427
val = SoQtViewer::VIEW_HIDDEN_LINE;
1429
case WIREFRAME_OVERLAY_ITEM:
1430
val = SoQtViewer::VIEW_WIREFRAME_OVERLAY;
1432
case NO_TEXTURE_ITEM:
1433
val = SoQtViewer::VIEW_NO_TEXTURE;
1435
case LOW_RESOLUTION_ITEM:
1436
val = SoQtViewer::VIEW_LOW_COMPLEXITY;
1438
case WIREFRAME_ITEM:
1439
val = SoQtViewer::VIEW_LINE;
1442
val = SoQtViewer::VIEW_POINT;
1444
case BOUNDING_BOX_ITEM:
1445
val = SoQtViewer::VIEW_BBOX;
1448
case MOVE_SAME_AS_STILL_ITEM:
1449
val = SoQtViewer::VIEW_SAME_AS_STILL;
1451
case MOVE_NO_TEXTURE_ITEM:
1452
val = SoQtViewer::VIEW_NO_TEXTURE;
1454
case MOVE_LOW_RES_ITEM:
1455
val = SoQtViewer::VIEW_LOW_COMPLEXITY;
1457
case MOVE_WIREFRAME_ITEM:
1458
val = SoQtViewer::VIEW_LINE;
1460
case MOVE_LOW_RES_WIREFRAME_ITEM:
1461
val = SoQtViewer::VIEW_LOW_RES_LINE;
1463
case MOVE_POINTS_ITEM:
1464
val = SoQtViewer::VIEW_POINT;
1466
case MOVE_LOW_RES_POINTS_ITEM:
1467
val = SoQtViewer::VIEW_LOW_RES_POINT;
1469
case MOVE_BOUNDING_BOX_ITEM:
1470
val = SoQtViewer::VIEW_BBOX;
1478
SoQtViewer::DrawType type = SoQtViewer::STILL;
1480
switch (menuitemid) {
1482
case HIDDEN_LINE_ITEM:
1483
case WIREFRAME_OVERLAY_ITEM:
1484
case NO_TEXTURE_ITEM:
1485
case LOW_RESOLUTION_ITEM:
1486
case WIREFRAME_ITEM:
1488
case BOUNDING_BOX_ITEM:
1489
type = SoQtViewer::STILL;
1492
case MOVE_SAME_AS_STILL_ITEM:
1493
case MOVE_NO_TEXTURE_ITEM:
1494
case MOVE_LOW_RES_ITEM:
1495
case MOVE_WIREFRAME_ITEM:
1496
case MOVE_LOW_RES_WIREFRAME_ITEM:
1497
case MOVE_POINTS_ITEM:
1498
case MOVE_LOW_RES_POINTS_ITEM:
1499
case MOVE_BOUNDING_BOX_ITEM:
1500
type = SoQtViewer::INTERACTIVE;
1508
PUBLIC(this)->setDrawStyle(type, val);
1511
// ************************************************************************
1513
// Move camera parallel with the plane orthogonal to the camera
1514
// direction vector.
1516
// Used from both SoGuiPlaneViewer and SoGuiExaminerViewer.
1517
// Implemented in the SoGuiFullViewer private class to collect common
1520
SoGuiFullViewerP::pan(SoCamera * cam,
1521
float aspectratio, const SbPlane & panningplane,
1522
const SbVec2f & currpos, const SbVec2f & prevpos)
1524
if (cam == NULL) return; // can happen for empty scenegraph
1525
if (currpos == prevpos) return; // useless invocation
1528
SoDebugError::postInfo("SoGuiFullViewerP::pan",
1529
"was(%.3g, %.3g) -> now(%.3g, %.3g)",
1530
prevpos[0], prevpos[1], currpos[0], currpos[1]);
1531
#endif // SOQT_DEBUG
1533
// Find projection points for the last and current mouse coordinates.
1534
SbViewVolume vv = cam->getViewVolume(aspectratio);
1536
vv.projectPointToLine(currpos, line);
1537
SbVec3f current_planept;
1538
panningplane.intersect(line, current_planept);
1539
vv.projectPointToLine(prevpos, line);
1540
SbVec3f old_planept;
1541
panningplane.intersect(line, old_planept);
1543
// Reposition camera according to the vector difference between the
1544
// projected points.
1545
cam->position = cam->position.getValue() - (current_planept - old_planept);
1548
// *************************************************************************
1550
// Dependent on the camera type this will either shrink or expand the
1551
// height of the viewport (orthogonal camera) or move the camera
1552
// closer or further away from the focal point in the scene.
1554
// Used from both SoGuiPlaneViewer and SoGuiExaminerViewer.
1555
// Implemented in the SoGuiFullViewer private class to collect common
1558
SoGuiFullViewerP::zoom(SoCamera * cam, const float diffvalue)
1560
if (cam == NULL) return; // can happen for empty scenegraph
1561
SoType t = cam->getTypeId();
1562
SbName tname = t.getName();
1564
// This will be in the range of <0, ->>.
1565
float multiplicator = float(exp(diffvalue));
1567
if (t.isDerivedFrom(SoOrthographicCamera::getClassTypeId())) {
1569
// Since there's no perspective, "zooming" in the original sense
1570
// of the word won't have any visible effect. So we just increase
1571
// or decrease the field-of-view values of the camera instead, to
1572
// "shrink" the projection size of the model / scene.
1573
SoOrthographicCamera * oc = (SoOrthographicCamera *)cam;
1574
oc->height = oc->height.getValue() * multiplicator;
1578
// FrustumCamera can be found in the SmallChange CVS module (it's
1579
// a camera that lets you specify (for instance) an off-center
1580
// frustum (similar to glFrustum())
1581
if (!t.isDerivedFrom(SoPerspectiveCamera::getClassTypeId()) &&
1582
tname != "FrustumCamera") {
1583
static SbBool first = TRUE;
1585
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
1586
"Unknown camera type, "
1587
"will zoom by moving position, but this might not be correct.");
1592
const float oldfocaldist = cam->focalDistance.getValue();
1593
const float newfocaldist = oldfocaldist * multiplicator;
1596
cam->orientation.getValue().multVec(SbVec3f(0, 0, -1), direction);
1598
const SbVec3f oldpos = cam->position.getValue();
1599
const SbVec3f newpos = oldpos + (newfocaldist - oldfocaldist) * -direction;
1601
// This catches a rather common user interface "buglet": if the
1602
// user zooms the camera out to a distance from origo larger than
1603
// what we still can safely do floating point calculations on
1604
// (i.e. without getting NaN or Inf values), the faulty floating
1605
// point values will propagate until we start to get debug error
1606
// messages and eventually an assert failure from core Coin code.
1608
// With the below bounds check, this problem is avoided.
1610
// (But note that we depend on the input argument ''diffvalue'' to
1611
// be small enough that zooming happens gradually. Ideally, we
1612
// should also check distorigo with isinf() and isnan() (or
1613
// inversely; isinfite()), but those only became standardized with
1615
const float distorigo = newpos.length();
1616
// sqrt(FLT_MAX) == ~ 1e+19, which should be both safe for further
1617
// calculations and ok for the end-user and app-programmer.
1618
if (distorigo > float(sqrt(FLT_MAX))) {
1619
#if SOQT_DEBUG && 0 // debug
1620
SoDebugError::postWarning("SoGuiFullViewerP::zoom",
1621
"zoomed too far (distance to origo==%f (%e))",
1622
distorigo, distorigo);
1626
cam->position = newpos;
1627
cam->focalDistance = newfocaldist;
1632
// ************************************************************************
1634
#endif // DOXYGEN_SKIP_THIS