1
/**************************************************************************\
3
* This file is part of the Coin 3D visualization library.
4
* Copyright (C) 1998-2003 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, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY.
20
* <URL:http://www.sim.no>.
22
\**************************************************************************/
24
// ************************************************************************
26
// Class is documented in common/viewers/SoGuiFullViewer.cpp.in.
28
// ************************************************************************
30
// FIXME: this sourcefile is way too large -- this reeks of bad
31
// design. Should try to factor out lots of stuff. 20010821 mortene.
33
// FIXME: can hide more stuff from the public header file into
34
// SoQtFullViewerP -- most or all of the private methods, for
35
// instance. 20010821 mortene.
37
// FIXME, low priority:
38
// * add tooltips to the widgets?
39
// * trim length of edit fields
43
#endif // HAVE_CONFIG_H
45
#include <qpushbutton.h>
49
#include <qlineedit.h>
50
#include <qbuttongroup.h>
51
#include <qradiobutton.h>
54
#include <qcheckbox.h>
55
#include <qmetaobject.h>
57
#ifdef HAVE_QSTYLEFACTORY_H
58
#include <qstylefactory.h>
59
#endif // HAVE_QSTYLEFACTORY_H
61
#include <Inventor/Qt/viewers/moc_SoQtFullViewerP.icc>
62
#include <Inventor/Qt/viewers/SoQtFullViewerP.h>
64
#include <Inventor/nodes/SoPerspectiveCamera.h>
65
#include <Inventor/nodes/SoOrthographicCamera.h>
66
#include <Inventor/errors/SoDebugError.h>
69
#include <Inventor/Qt/SoQt.h>
70
#include <Inventor/Qt/widgets/SoQtThumbWheel.h>
71
#include <Inventor/Qt/widgets/SoQtPopupMenu.h>
72
#include <Inventor/Qt/viewers/SoQtFullViewer.h>
73
#include <Inventor/Qt/SoAny.h>
76
#include <Inventor/Qt/common/pixmaps/pick.xpm>
77
#include <Inventor/Qt/common/pixmaps/view.xpm>
78
#include <Inventor/Qt/common/pixmaps/home.xpm>
79
#include <Inventor/Qt/common/pixmaps/set_home.xpm>
80
#include <Inventor/Qt/common/pixmaps/view_all.xpm>
81
#include <Inventor/Qt/common/pixmaps/seek.xpm>
83
// *************************************************************************
85
SOQT_OBJECT_ABSTRACT_SOURCE(SoQtFullViewer);
87
// *************************************************************************
89
// *************************************************************************
91
static const int VIEWERBORDER = 2;
92
static const int ZOOMSLIDERRESOLUTION = 200;
94
// *************************************************************************
96
// Button index values.
106
// *************************************************************************
108
#define PUBLIC(o) (o->pub)
109
#define PRIVATE(o) (o->pimpl)
111
// *************************************************************************
113
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
114
SoQtFullViewer::SoQtFullViewer(QWidget * parent,
117
SoQtFullViewer::BuildFlag buildFlag,
118
SoQtViewer::Type type,
120
: inherited(parent, name, embed, type, FALSE)
122
PRIVATE(this) = new SoQtFullViewerP(this);
124
PRIVATE(this)->viewerwidget = NULL;
125
PRIVATE(this)->canvas = NULL;
126
// PRIVATE(this)->canvasparent = NULL;
128
PRIVATE(this)->viewbutton = NULL;
129
PRIVATE(this)->interactbutton = NULL;
131
this->leftDecoration = NULL;
132
this->bottomDecoration = NULL;
133
this->rightDecoration = NULL;
135
this->leftWheel = NULL;
136
this->leftWheelLabel = NULL;
137
this->leftWheelStr = NULL;
138
this->leftWheelVal = 0.0f;
140
this->bottomWheel = NULL;
141
this->bottomWheelLabel = NULL;
142
this->bottomWheelStr = NULL;
143
this->bottomWheelVal = 0.0f;
145
this->rightWheel = NULL;
146
this->rightWheelLabel = NULL;
147
this->rightWheelStr = NULL;
148
this->rightWheelVal = 0.0f;
150
this->setLeftWheelString("Motion X");
151
this->setBottomWheelString("Motion Y");
152
this->setRightWheelString("Motion Z");
154
PRIVATE(this)->mainlayout = NULL;
155
PRIVATE(this)->appbuttonlayout = NULL;
157
PRIVATE(this)->menuenabled = buildFlag & SoQtFullViewer::BUILD_POPUP;
158
PRIVATE(this)->decorations =
159
(buildFlag & SoQtFullViewer::BUILD_DECORATION) ? TRUE : FALSE;
161
this->prefmenu = NULL;
162
PRIVATE(this)->menutitle = "Viewer Menu";
164
PRIVATE(this)->viewerbuttons = new SbPList;
165
PRIVATE(this)->appbuttonlist = new SbPList;
166
PRIVATE(this)->appbuttonform = NULL;
168
this->setSize(SbVec2s(500, 390));
172
this->setClassName("SoQtFullViewer");
173
QWidget * viewer = this->buildWidget(this->getParentWidget());
174
this->setBaseWidget(viewer);
177
// *************************************************************************
179
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
180
SoQtFullViewer::~SoQtFullViewer()
182
if (PRIVATE(this)->viewerwidget) {
183
this->unregisterWidget(PRIVATE(this)->viewerwidget);
186
delete PRIVATE(this)->viewerbuttons;
187
delete PRIVATE(this)->appbuttonlist;
189
delete [] this->leftWheelStr;
190
delete [] this->rightWheelStr;
191
delete [] this->bottomWheelStr;
193
delete PRIVATE(this);
196
// *************************************************************************
198
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
200
SoQtFullViewer::setDecoration(const SbBool enable)
203
if ((enable && this->isDecoration()) ||
204
(!enable && !this->isDecoration())) {
205
SoDebugError::postWarning("SoQtFullViewer::setDecoration",
206
"decorations already turned %s",
207
enable ? "on" : "off");
212
PRIVATE(this)->decorations = enable;
213
if (PRIVATE(this)->viewerwidget)
214
PRIVATE(this)->showDecorationWidgets(enable);
217
// *************************************************************************
219
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
221
SoQtFullViewer::isDecoration(void) const
223
return PRIVATE(this)->decorations;
226
// *************************************************************************
228
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
230
SoQtFullViewer::setPopupMenuEnabled(const SbBool enable)
233
if ((enable && this->isPopupMenuEnabled()) ||
234
(!enable && !this->isPopupMenuEnabled())) {
235
SoDebugError::postWarning("SoQtFullViewer::setPopupMenuEnabled",
236
"popup menu already turned %s",
237
enable ? "on" : "off");
241
PRIVATE(this)->menuenabled = enable;
244
// *************************************************************************
246
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
248
SoQtFullViewer::isPopupMenuEnabled(void) const
250
return PRIVATE(this)->menuenabled;
253
// *************************************************************************
255
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
257
SoQtFullViewer::getAppPushButtonParent(void) const
259
return PRIVATE(this)->appbuttonform;
262
// *************************************************************************
264
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
266
SoQtFullViewer::addAppPushButton(QWidget * newButton)
268
PRIVATE(this)->appbuttonlist->append(newButton);
269
PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
272
// *************************************************************************
274
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
276
SoQtFullViewer::insertAppPushButton(QWidget * newButton, int index)
279
if ((index < 0) || (index > this->lengthAppPushButton())) {
280
SoDebugError::postWarning("SoQtFullViewer::insertAppPushButton",
281
"index %d out of bounds", index);
285
PRIVATE(this)->appbuttonlist->insert(newButton, index);
286
PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
289
// *************************************************************************
291
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
293
SoQtFullViewer::removeAppPushButton(QWidget * oldButton)
295
int idx = PRIVATE(this)->appbuttonlist->find(oldButton);
299
SoDebugError::postWarning("SoQtFullViewer::removeAppPushButton",
300
"tried to remove non-existant button");
305
PRIVATE(this)->appbuttonlist->remove(idx);
306
PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
309
// *************************************************************************
311
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
313
SoQtFullViewer::findAppPushButton(QWidget * oldButton) const
315
return PRIVATE(this)->appbuttonlist->find(oldButton);
318
// *************************************************************************
320
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
322
SoQtFullViewer::lengthAppPushButton(void) const
324
return PRIVATE(this)->appbuttonlist->getLength();
327
// *************************************************************************
329
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
331
SoQtFullViewer::getRenderAreaWidget(void) const
333
return PRIVATE(this)->canvas;
336
// *************************************************************************
338
// Documented in superclass. Overridden from parent class to correctly
339
// set the user interface indicators on the current state, i.e. to
340
// flip the examine and interact pushbuttons and to grey out the seek
341
// mode activation button iff in interact mode.
343
SoQtFullViewer::setViewing(SbBool enable)
345
if ((enable && this->isViewing()) ||
346
(!enable && !this->isViewing())) {
347
#if SOQT_DEBUG && 0 // debug
348
SoDebugError::postWarning("SoQtFullViewer::setViewing",
349
"view mode already %s", on ? "on" : "off");
354
inherited::setViewing(enable);
356
// Must check that buttons have been built, in case this viewer
357
// component was made without decorations.
358
if (PRIVATE(this)->viewerbuttons->getLength() > 0) {
359
PRIVATE(this)->getViewerbutton(EXAMINE_BUTTON)->setOn(enable);
360
PRIVATE(this)->getViewerbutton(INTERACT_BUTTON)->setOn(enable ? FALSE : TRUE);
361
PRIVATE(this)->getViewerbutton(SEEK_BUTTON)->setEnabled(enable);
365
// *************************************************************************
367
// Documented in superclass.
369
SoQtFullViewer::buildWidget(QWidget * parent)
371
// This will build the main view widgets, along with the decorations
372
// widgets and popup menu if they are enabled.
375
SoDebugError::postInfo("SoQtFullViewer::buildWidget", "[invoked]");
378
PRIVATE(this)->viewerwidget = new QWidget(parent);
379
this->registerWidget(PRIVATE(this)->viewerwidget);
381
PRIVATE(this)->viewerwidget->move(0, 0);
384
PRIVATE(this)->viewerwidget->setBackgroundColor(QColor(250, 0, 0));
387
// FIXME: The scaling and layout of a viewer without decorations
388
// currently don't work, so here I create the widget /with/
389
// decorations, and desides if they should be visible afterwards. A
390
// nice side-effect is that this makes sure that the
391
// (SoQtFullViewer*)->setDecoration(SbBool) works for TRUE and
392
// FALSE, regardless of how the widget initially was built. I regard
393
// this more like a workaround than as a /fix/, and lots and lots of
394
// this should have a major brushing as there still are a lot of
395
// evil-doers in this county.... 20021022 rolvs.
397
PRIVATE(this)->canvas = inherited::buildWidget(PRIVATE(this)->viewerwidget);
399
QSize s(PRIVATE(this)->viewerwidget->size().width(),
400
PRIVATE(this)->viewerwidget->size().height());
402
PRIVATE(this)->canvas->resize(s);
404
this->buildDecoration( PRIVATE(this)->viewerwidget );
405
PRIVATE(this)->showDecorationWidgets( PRIVATE(this)->decorations );
407
if (PRIVATE(this)->menuenabled)
408
this->buildPopupMenu();
410
return PRIVATE(this)->viewerwidget;
413
// *************************************************************************
415
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
417
SoQtFullViewer::buildDecoration(QWidget * parent)
419
this->leftDecoration = this->buildLeftTrim(parent);
420
this->bottomDecoration = this->buildBottomTrim(parent);
421
this->rightDecoration = this->buildRightTrim(parent);
424
// *************************************************************************
426
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
428
SoQtFullViewer::buildLeftTrim(QWidget * parent)
430
QWidget * w = new QWidget(parent);
431
w->setFixedWidth(30);
433
QGridLayout * gl = new QGridLayout(w, 3, 1, 2, -1);
434
gl->addWidget(this->buildAppButtons(w), 0, 0);
436
SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Vertical, w);
438
t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
439
this->leftWheelVal = t->value();
441
QObject::connect(t, SIGNAL(wheelMoved(float)), PRIVATE(this), SLOT(leftWheelChanged(float)));
442
QObject::connect(t, SIGNAL(wheelPressed()), PRIVATE(this), SLOT(leftWheelPressed()));
443
QObject::connect(t, SIGNAL(wheelReleased()), PRIVATE(this), SLOT(leftWheelReleased()));
445
gl->addWidget(t, 2, 0, Qt::AlignBottom | Qt::AlignHCenter);
451
// *************************************************************************
453
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
455
SoQtFullViewer::buildBottomTrim(QWidget * parent)
457
QWidget * w = new QWidget(parent);
458
w->setFixedHeight(30);
460
QLabel * label = new QLabel(this->leftWheelStr, w);
462
label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
464
this->leftWheelLabel = label;
466
label = new QLabel(this->bottomWheelStr, w);
468
label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
470
this->bottomWheelLabel = label;
472
label = new QLabel(this->rightWheelStr, w);
474
label->setAlignment(Qt::AlignRight | Qt::AlignTop);
476
this->rightWheelLabel = label;
478
SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Horizontal, w);
479
this->bottomWheel = t;
480
t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
482
QObject::connect(t, SIGNAL(wheelMoved(float)),
483
PRIVATE(this), SLOT(bottomWheelChanged(float)));
484
QObject::connect(t, SIGNAL(wheelPressed()),
485
PRIVATE(this), SLOT(bottomWheelPressed()));
486
QObject::connect(t, SIGNAL(wheelReleased()),
487
PRIVATE(this), SLOT(bottomWheelReleased()));
489
this->bottomWheelVal = t->value();
491
QGridLayout * gl = new QGridLayout(w, 1, 5);
492
gl->setColStretch(0, 0);
493
gl->setColStretch(1, 0);
494
gl->setColStretch(2, 0);
495
gl->setColStretch(3, 1);
496
gl->setColStretch(4, 0);
498
gl->addWidget(this->leftWheelLabel, 0, 0, Qt::AlignVCenter | Qt::AlignHCenter);
499
gl->addWidget(this->bottomWheelLabel, 0, 1, Qt::AlignVCenter | Qt::AlignRight);
500
gl->addWidget(t, 0, 2, Qt::AlignVCenter | Qt::AlignLeft);
501
gl->addWidget(this->rightWheelLabel, 0, 4, Qt::AlignVCenter | Qt::AlignRight);
508
// *************************************************************************
510
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
512
SoQtFullViewer::buildRightTrim(QWidget * parent)
514
QWidget * w = new QWidget(parent);
515
// FIXME: should be set according to width of viewer
516
// buttons. 20000424 mortene.
517
w->setFixedWidth(30);
518
// FIXME: nope, trims are actually guaranteed to be 30 pixels wide
520
SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Vertical, w);
521
this->rightWheel = t;
522
t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
523
this->rightWheelVal = t->value();
525
QObject::connect(t, SIGNAL(wheelMoved(float)),
526
PRIVATE(this), SLOT(rightWheelChanged(float)));
527
QObject::connect(t, SIGNAL(wheelPressed()),
528
PRIVATE(this), SLOT(rightWheelPressed()));
529
QObject::connect(t, SIGNAL(wheelReleased()),
530
PRIVATE(this), SLOT(rightWheelReleased()));
532
QGridLayout * l = new QGridLayout(w, 3, 1, 2, -1);
534
l->addWidget(this->buildViewerButtons(w), 0, 0);
535
l->addWidget(t, 2, 0, Qt::AlignBottom | Qt::AlignHCenter);
541
// *************************************************************************
543
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
545
SoQtFullViewer::buildAppButtons(QWidget * parent)
547
PRIVATE(this)->appbuttonform = new QWidget(parent);
549
if (this->lengthAppPushButton() > 0)
550
PRIVATE(this)->layoutAppButtons(PRIVATE(this)->appbuttonform);
552
return PRIVATE(this)->appbuttonform;
555
// *************************************************************************
557
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
559
SoQtFullViewer::buildViewerButtons(QWidget * parent)
561
QWidget * w = new QWidget(parent);
562
this->createViewerButtons(w, PRIVATE(this)->viewerbuttons);
565
// assert(PRIVATE(this)->viewerbuttons->getLength() != 0);
567
new QGridLayout(w, PRIVATE(this)->viewerbuttons->getLength(), 1);
571
const int numViewerButtons = PRIVATE(this)->viewerbuttons->getLength();
572
for (int i = 0; i < numViewerButtons; i++) {
573
QButton * b = PRIVATE(this)->getViewerbutton(i);
574
b->setFixedSize(30, 30);
575
b->setFocusPolicy(QWidget::NoFocus);
576
l->addWidget(b, i, 0);
583
// *************************************************************************
585
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
587
SoQtFullViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
589
for (int i=0; i <= SEEK_BUTTON; i++) {
590
QPushButton * p = new QPushButton(parent);
591
// Button focus doesn't really make sense in the way we're using
593
p->setFocusPolicy(QWidget::NoFocus);
595
#if (defined Q_WS_MAC && QT_VERSION >= 0x030100) && defined(HAVE_QSTYLEFACTORY_H)
596
// Since Qt/Mac 3.1.x, all pushbuttons (even those < 32x32) are drawn
597
// using the Aqua style, i.e. with rounded edges and shading. This
598
// looks really ugly in the viewer decoration. Drawing the buttons
599
// in the Windows style gives us the flat, square buttons we want.
600
QStyle * style = QStyleFactory::create("windows");
601
if (style) { p->setStyle(style); }
604
// FIXME: its wrong to cast xpm data to (const char **), it
605
// _should_ be (const char * const []), but this is not valid ANSI
606
// C++. Not sure what to do about this (and the wrong cast can
607
// (and has) in fact lead to bugs, so the situation should be
608
// resolved). 20000505 mortene.
611
case INTERACT_BUTTON:
612
PRIVATE(this)->interactbutton = p;
613
p->setToggleButton(TRUE);
614
p->setPixmap(QPixmap((const char **)pick_xpm));
615
p->setOn(this->isViewing() ? FALSE : TRUE);
616
QObject::connect(p, SIGNAL(clicked()),
617
PRIVATE(this), SLOT(interactbuttonClicked()));
620
PRIVATE(this)->viewbutton = p;
621
p->setToggleButton(TRUE);
622
p->setPixmap(QPixmap((const char **)view_xpm));
623
p->setOn(this->isViewing());
624
QObject::connect(p, SIGNAL(clicked()),
625
PRIVATE(this), SLOT(viewbuttonClicked()));
628
QObject::connect(p, SIGNAL(clicked()), PRIVATE(this), SLOT(homebuttonClicked()));
629
p->setPixmap(QPixmap((const char **)home_xpm));
631
case SET_HOME_BUTTON:
632
QObject::connect(p, SIGNAL(clicked()),
633
PRIVATE(this), SLOT(sethomebuttonClicked()));
634
p->setPixmap(QPixmap((const char **)set_home_xpm));
636
case VIEW_ALL_BUTTON:
637
QObject::connect(p, SIGNAL(clicked()),
638
PRIVATE(this), SLOT(viewallbuttonClicked()));
639
p->setPixmap(QPixmap((const char **)view_all_xpm));
642
QObject::connect(p, SIGNAL(clicked()), PRIVATE(this), SLOT(seekbuttonClicked()));
643
p->setPixmap(QPixmap((const char **)seek_xpm));
651
buttonlist->append(p);
655
// *************************************************************************
657
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
659
SoQtFullViewer::buildPopupMenu(void)
661
this->prefmenu = PRIVATE(this)->setupStandardPopupMenu();
664
// *************************************************************************
666
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
668
SoQtFullViewer::openPopupMenu(const SbVec2s position)
670
if (! this->isPopupMenuEnabled()) return;
671
if (this->prefmenu == NULL)
672
this->buildPopupMenu();
673
int x = 2 + position[0];
674
int y = 2 + this->getGLSize()[1] - position[1] - 1;
676
PRIVATE(this)->prepareMenu(this->prefmenu);
677
this->prefmenu->popUp(this->getGLWidget(), x, y);
680
// *************************************************************************
682
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
684
SoQtFullViewer::setLeftWheelString(const char * const string)
686
delete [] this->leftWheelStr;
687
this->leftWheelStr = NULL;
690
this->leftWheelStr = strcpy(new char [strlen(string)+1], string);
691
if (this->leftWheelLabel)
692
((QLabel *)this->leftWheelLabel)->setText(string ? string : "");
695
// *************************************************************************
697
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
699
SoQtFullViewer::setBottomWheelString(const char * const string)
701
delete [] this->bottomWheelStr;
702
this->bottomWheelStr = NULL;
705
this->bottomWheelStr = strcpy(new char [strlen(string)+1], string);
706
if (this->bottomWheelLabel)
707
((QLabel *)this->bottomWheelLabel)->setText(string ? string : "");
710
// *************************************************************************
712
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
714
SoQtFullViewer::setRightWheelString(const char * const string)
716
delete [] this->rightWheelStr;
717
this->rightWheelStr = NULL;
720
this->rightWheelStr = strcpy(new char [strlen(string)+1], string);
721
if (this->rightWheelLabel)
722
((QLabel *)this->rightWheelLabel)->setText(string ? string : "");
725
// *************************************************************************
729
SoQtFullViewer::sizeChanged(const SbVec2s & size)
732
SoDebugError::postInfo("SoQtFullViewer::sizeChanged", "(%d, %d)",
736
SbVec2s newsize(size);
737
if (PRIVATE(this)->decorations) {
738
newsize[0] -= this->leftDecoration ? this->leftDecoration->width() : 0;
739
newsize[0] -= this->rightDecoration ? this->rightDecoration->width() : 0;
740
newsize[1] -= this->bottomDecoration ? this->bottomDecoration->height() : 0;
743
// Workaround for a bug in Qt/Mac 3.1.0 and 3.1.1 (which has been
744
// confirmed fixed in 3.1.2):
746
// If the OpenGL context overlaps with the QSizeGrip widget
747
// (generated by default), resizing does not work any more. The
748
// workaround is to leave 15 pixels at the lower border of the
750
#if defined Q_WS_MAC && ((QT_VERSION == 0x030100) || (QT_VERSION == 0x030101))
752
// Environment variable to override Qt/Mac 3.1.x workarounds.
753
const char * forcenoresizeworkaround =
754
SoAny::si()->getenv("FORCE_NO_QTMAC_31_RESIZE_WORKAROUND");
755
if (!forcenoresizeworkaround || (atoi(forcenoresizeworkaround) == 0)) {
757
if (!PRIVATE(this)->decorations) { // GL context would fill whole window
758
newsize -= SbVec2s(0, 15); // -> leave lowermost 15 px blank
760
// spit out a warning that this is a Qt/Mac bug, not an SoQt problem
761
const char * env = SoAny::si()->getenv("SOQT_NO_QTMAC_BUG_WARNINGS");
762
if (!env || !atoi(env)) {
763
SoDebugError::postWarning("SoQtFullViewer::sizeChanged",
764
"\nThis version of Qt/Mac contains a bug "
765
"that makes it necessary to leave the\n"
766
"lowermost 15 pixels of the viewer window "
767
"blank. Set the environment variable\n"
768
"FORCE_NO_QTMAC_31_RESIZE_WORKAROUND=1 to "
769
"override this workaround. \n"
770
"You can turn off warnings about Qt/Mac "
771
"bugs permanently by setting \n"
772
"SOQT_NO_QTMAC_BUG_WARNINGS=1.\n");
779
newsize = SbVec2s(SoQtMax(newsize[0], (short)1),
780
SoQtMax(newsize[1], (short)1));
782
inherited::sizeChanged(newsize);
785
// *************************************************************************
787
#ifndef DOXYGEN_SKIP_THIS
789
// Show or hide decorations. Will make and activate a Qt layout grid
790
// if we're turning the decorations on.
792
SoQtFullViewerP::showDecorationWidgets(SbBool onOff)
795
SoDebugError::postInfo("SoQtFullViewerP::showDecorationWidgets", "[invoked]");
798
if (this->mainlayout) delete this->mainlayout;
800
assert(this->viewerwidget);
801
// assert(this->canvasparent);
803
assert(PUBLIC(this)->leftDecoration && PUBLIC(this)->bottomDecoration && PUBLIC(this)->rightDecoration);
805
PUBLIC(this)->leftDecoration->show();
806
PUBLIC(this)->bottomDecoration->show();
807
PUBLIC(this)->rightDecoration->show();
809
QGridLayout * g = new QGridLayout(this->viewerwidget, 2, 1, 0, -1); // VIEWERBORDER);
811
g->addWidget(PUBLIC(this)->bottomDecoration, 1, 0);
813
QGridLayout * subLayout = new QGridLayout(1, 3, 0);
814
g->addLayout(subLayout, 0, 0);
816
subLayout->addWidget(PUBLIC(this)->leftDecoration, 0, 0);
817
subLayout->addWidget(this->canvas, 0, 1);
818
subLayout->addWidget(PUBLIC(this)->rightDecoration, 0, 2);
820
// subLayout->setColStretch(1, 1);
821
// g->setRowStretch(0, 1);
823
this->mainlayout = g;
825
QGridLayout * g = new QGridLayout(this->viewerwidget, 1, 1, 0, -1);
826
g->addWidget(this->canvas, 0, 0);
827
this->mainlayout = g;
829
PUBLIC(this)->leftDecoration->hide();
830
PUBLIC(this)->bottomDecoration->hide();
831
PUBLIC(this)->rightDecoration->hide();
834
this->mainlayout->activate();
835
QSize size = this->viewerwidget->size();
836
SbVec2s rasize = SbVec2s(size.width(), size.height());
837
PUBLIC(this)->sizeChanged(rasize);
840
// *************************************************************************
842
// Layout application specified buttons.
844
SoQtFullViewerP::layoutAppButtons(QWidget * form)
846
delete this->appbuttonlayout; this->appbuttonlayout = NULL;
848
int nrbuttons = this->appbuttonlist->getLength();
849
if (nrbuttons == 0) return;
851
this->appbuttonlayout = new QGridLayout(form, nrbuttons, 1);
853
for (int i=0; i < nrbuttons; i++) {
854
QWidget * button = (QWidget *)((*(this->appbuttonlist))[i]);
856
((QGridLayout *)this->appbuttonlayout)->addWidget(button, i, 0);
859
this->appbuttonlayout->activate();
862
// *************************************************************************
866
SoQtFullViewerP::interactbuttonClicked(void)
868
if (this->interactbutton)
869
((QPushButton *)this->interactbutton)->setOn(TRUE);
870
if (this->viewbutton)
871
((QPushButton *)this->viewbutton)->setOn(FALSE);
872
if (PUBLIC(this)->isViewing())
873
PUBLIC(this)->setViewing(FALSE);
876
// *************************************************************************
880
SoQtFullViewerP::viewbuttonClicked(void)
882
if (this->interactbutton)
883
((QPushButton *)this->interactbutton)->setOn(FALSE);
884
if (this->viewbutton)
885
((QPushButton *)this->viewbutton)->setOn(TRUE);
886
if (!PUBLIC(this)->isViewing())
887
PUBLIC(this)->setViewing(TRUE);
890
// *************************************************************************
894
SoQtFullViewerP::homebuttonClicked()
896
PUBLIC(this)->resetToHomePosition();
899
// *************************************************************************
903
SoQtFullViewerP::sethomebuttonClicked()
905
PUBLIC(this)->saveHomePosition();
908
// *************************************************************************
912
SoQtFullViewerP::viewallbuttonClicked()
914
PUBLIC(this)->viewAll();
917
// *************************************************************************
921
SoQtFullViewerP::seekbuttonClicked()
923
PUBLIC(this)->setSeekMode(PUBLIC(this)->isSeekMode() ? FALSE : TRUE);
926
// *************************************************************************
930
SoQtFullViewerP::selectedViewing()
932
PUBLIC(this)->setViewing(PUBLIC(this)->isViewing() ? FALSE : TRUE);
935
// *************************************************************************
939
SoQtFullViewerP::selectedDecoration()
941
PUBLIC(this)->setDecoration(PUBLIC(this)->isDecoration() ? FALSE : TRUE);
944
// *************************************************************************
948
SoQtFullViewerP::selectedHeadlight()
950
PUBLIC(this)->setHeadlight(PUBLIC(this)->isHeadlight() ? FALSE : TRUE);
953
// *************************************************************************
957
SoQtFullViewerP::increaseInteractiveCount()
959
PUBLIC(this)->interactiveCountInc();
962
// *************************************************************************
966
SoQtFullViewerP::decreaseInteractiveCount()
968
PUBLIC(this)->interactiveCountDec();
971
// *************************************************************************
973
SoQtFullViewerP::SoQtFullViewerP(SoQtFullViewer * publ)
974
: SoGuiFullViewerP(publ)
978
SoQtFullViewerP::~SoQtFullViewerP()
983
SoQtFullViewerP::setThumbWheelValue(void * wheel, float val)
985
((SoQtThumbWheel *)wheel)->setValue(val);
988
// *************************************************************************
990
// These are all private slots for catching Qt events.
991
void SoQtFullViewerP::leftWheelPressed(void) { PUBLIC(this)->leftWheelStart(); }
992
void SoQtFullViewerP::leftWheelChanged(float v) { PUBLIC(this)->leftWheelMotion(v); }
993
void SoQtFullViewerP::leftWheelReleased(void) { PUBLIC(this)->leftWheelFinish(); }
994
void SoQtFullViewerP::bottomWheelPressed(void) { PUBLIC(this)->bottomWheelStart(); }
995
void SoQtFullViewerP::bottomWheelChanged(float v) { PUBLIC(this)->bottomWheelMotion(v);}
996
void SoQtFullViewerP::bottomWheelReleased(void) { PUBLIC(this)->bottomWheelFinish(); }
997
void SoQtFullViewerP::rightWheelPressed(void) { PUBLIC(this)->rightWheelStart(); }
998
void SoQtFullViewerP::rightWheelChanged(float v) { PUBLIC(this)->rightWheelMotion(v); }
999
void SoQtFullViewerP::rightWheelReleased(void) { PUBLIC(this)->rightWheelFinish(); }
1001
// *************************************************************************
1003
#endif // DOXYGEN_SKIP_THIS