~ubuntu-branches/ubuntu/oneiric/soqt/oneiric

« back to all changes in this revision

Viewing changes to src/Inventor/Qt/viewers/FullViewer.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Steve M. Robbins
  • Date: 2004-05-29 02:58:50 UTC
  • Revision ID: james.westby@ubuntu.com-20040529025850-phd20eva5uyhhdrf
Tags: upstream-1.0.2
ImportĀ upstreamĀ versionĀ 1.0.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**************************************************************************\
 
2
 *
 
3
 *  This file is part of the Coin 3D visualization library.
 
4
 *  Copyright (C) 1998-2003 by Systems in Motion.  All rights reserved.
 
5
 *
 
6
 *  This library is free software; you can redistribute it and/or
 
7
 *  modify it under the terms of the GNU General Public License
 
8
 *  ("GPL") version 2 as published by the Free Software Foundation.
 
9
 *  See the file LICENSE.GPL at the root directory of this source
 
10
 *  distribution for additional information about the GNU GPL.
 
11
 *
 
12
 *  For using Coin with software that can not be combined with the GNU
 
13
 *  GPL, and for taking advantage of the additional benefits of our
 
14
 *  support services, please contact Systems in Motion about acquiring
 
15
 *  a Coin Professional Edition License.
 
16
 *
 
17
 *  See <URL:http://www.coin3d.org> for more information.
 
18
 *
 
19
 *  Systems in Motion, Teknobyen, Abels Gate 5, 7030 Trondheim, NORWAY.
 
20
 *  <URL:http://www.sim.no>.
 
21
 *
 
22
\**************************************************************************/
 
23
 
 
24
// ************************************************************************
 
25
 
 
26
// Class is documented in common/viewers/SoGuiFullViewer.cpp.in.
 
27
 
 
28
// ************************************************************************
 
29
 
 
30
// FIXME: this sourcefile is way too large -- this reeks of bad
 
31
// design. Should try to factor out lots of stuff. 20010821 mortene.
 
32
 
 
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.
 
36
 
 
37
//    FIXME, low priority:
 
38
//     * add tooltips to the widgets?
 
39
//     * trim length of edit fields
 
40
 
 
41
#ifdef HAVE_CONFIG_H
 
42
#include <config.h>
 
43
#endif // HAVE_CONFIG_H
 
44
 
 
45
#include <qpushbutton.h>
 
46
#include <qlayout.h>
 
47
#include <qlabel.h>
 
48
#include <qpixmap.h>
 
49
#include <qlineedit.h>
 
50
#include <qbuttongroup.h>
 
51
#include <qradiobutton.h>
 
52
#include <qframe.h>
 
53
#include <qslider.h>
 
54
#include <qcheckbox.h>
 
55
#include <qmetaobject.h>
 
56
 
 
57
#ifdef HAVE_QSTYLEFACTORY_H
 
58
#include <qstylefactory.h>
 
59
#endif // HAVE_QSTYLEFACTORY_H
 
60
 
 
61
#include <Inventor/Qt/viewers/moc_SoQtFullViewerP.icc>
 
62
#include <Inventor/Qt/viewers/SoQtFullViewerP.h>
 
63
 
 
64
#include <Inventor/nodes/SoPerspectiveCamera.h>
 
65
#include <Inventor/nodes/SoOrthographicCamera.h>
 
66
#include <Inventor/errors/SoDebugError.h>
 
67
 
 
68
#include <soqtdefs.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> 
 
74
 
 
75
// Button icons.
 
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>
 
82
 
 
83
// *************************************************************************
 
84
 
 
85
SOQT_OBJECT_ABSTRACT_SOURCE(SoQtFullViewer);
 
86
 
 
87
// *************************************************************************
 
88
 
 
89
// *************************************************************************
 
90
 
 
91
static const int VIEWERBORDER = 2;
 
92
static const int ZOOMSLIDERRESOLUTION = 200;
 
93
 
 
94
// *************************************************************************
 
95
 
 
96
// Button index values.
 
97
enum {
 
98
  INTERACT_BUTTON = 0,
 
99
  EXAMINE_BUTTON,
 
100
  HOME_BUTTON,
 
101
  SET_HOME_BUTTON,
 
102
  VIEW_ALL_BUTTON,
 
103
  SEEK_BUTTON
 
104
};
 
105
 
 
106
// *************************************************************************
 
107
 
 
108
#define PUBLIC(o) (o->pub)
 
109
#define PRIVATE(o) (o->pimpl)
 
110
 
 
111
// *************************************************************************
 
112
 
 
113
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
114
SoQtFullViewer::SoQtFullViewer(QWidget * parent,
 
115
                               const char * name,
 
116
                               SbBool embed,
 
117
                               SoQtFullViewer::BuildFlag buildFlag,
 
118
                               SoQtViewer::Type type,
 
119
                               SbBool build)
 
120
  : inherited(parent, name, embed, type, FALSE)
 
121
{
 
122
  PRIVATE(this) = new SoQtFullViewerP(this);
 
123
 
 
124
  PRIVATE(this)->viewerwidget = NULL;
 
125
  PRIVATE(this)->canvas = NULL;
 
126
//  PRIVATE(this)->canvasparent = NULL;
 
127
 
 
128
  PRIVATE(this)->viewbutton = NULL;
 
129
  PRIVATE(this)->interactbutton = NULL;
 
130
 
 
131
  this->leftDecoration = NULL;
 
132
  this->bottomDecoration = NULL;
 
133
  this->rightDecoration = NULL;
 
134
 
 
135
  this->leftWheel = NULL;
 
136
  this->leftWheelLabel = NULL;
 
137
  this->leftWheelStr = NULL;
 
138
  this->leftWheelVal = 0.0f;
 
139
 
 
140
  this->bottomWheel = NULL;
 
141
  this->bottomWheelLabel = NULL;
 
142
  this->bottomWheelStr = NULL;
 
143
  this->bottomWheelVal = 0.0f;
 
144
 
 
145
  this->rightWheel = NULL;
 
146
  this->rightWheelLabel = NULL;
 
147
  this->rightWheelStr = NULL;
 
148
  this->rightWheelVal = 0.0f;
 
149
 
 
150
  this->setLeftWheelString("Motion X");
 
151
  this->setBottomWheelString("Motion Y");
 
152
  this->setRightWheelString("Motion Z");
 
153
 
 
154
  PRIVATE(this)->mainlayout = NULL;
 
155
  PRIVATE(this)->appbuttonlayout = NULL;
 
156
 
 
157
  PRIVATE(this)->menuenabled = buildFlag & SoQtFullViewer::BUILD_POPUP;
 
158
  PRIVATE(this)->decorations =
 
159
    (buildFlag & SoQtFullViewer::BUILD_DECORATION) ? TRUE : FALSE;
 
160
 
 
161
  this->prefmenu = NULL;
 
162
  PRIVATE(this)->menutitle = "Viewer Menu";
 
163
 
 
164
  PRIVATE(this)->viewerbuttons = new SbPList;
 
165
  PRIVATE(this)->appbuttonlist = new SbPList;
 
166
  PRIVATE(this)->appbuttonform = NULL;
 
167
 
 
168
  this->setSize(SbVec2s(500, 390));
 
169
 
 
170
  if (! build) return;
 
171
 
 
172
  this->setClassName("SoQtFullViewer");
 
173
  QWidget * viewer = this->buildWidget(this->getParentWidget());
 
174
  this->setBaseWidget(viewer);
 
175
}
 
176
 
 
177
// *************************************************************************
 
178
 
 
179
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
180
SoQtFullViewer::~SoQtFullViewer()
 
181
{
 
182
  if (PRIVATE(this)->viewerwidget) {
 
183
    this->unregisterWidget(PRIVATE(this)->viewerwidget);
 
184
  }
 
185
 
 
186
  delete PRIVATE(this)->viewerbuttons;
 
187
  delete PRIVATE(this)->appbuttonlist;
 
188
 
 
189
  delete [] this->leftWheelStr;
 
190
  delete [] this->rightWheelStr;
 
191
  delete [] this->bottomWheelStr;
 
192
 
 
193
  delete PRIVATE(this);
 
194
}
 
195
 
 
196
// *************************************************************************
 
197
 
 
198
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
199
void
 
200
SoQtFullViewer::setDecoration(const SbBool enable)
 
201
{
 
202
#if SOQT_DEBUG
 
203
  if ((enable  && this->isDecoration()) ||
 
204
       (!enable && !this->isDecoration())) {
 
205
    SoDebugError::postWarning("SoQtFullViewer::setDecoration",
 
206
                              "decorations already turned %s",
 
207
                              enable ? "on" : "off");
 
208
    return;
 
209
  }
 
210
#endif // SOQT_DEBUG
 
211
 
 
212
  PRIVATE(this)->decorations = enable;
 
213
  if (PRIVATE(this)->viewerwidget)
 
214
    PRIVATE(this)->showDecorationWidgets(enable);
 
215
}
 
216
 
 
217
// *************************************************************************
 
218
 
 
219
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
220
SbBool
 
221
SoQtFullViewer::isDecoration(void) const
 
222
{
 
223
  return PRIVATE(this)->decorations;
 
224
}
 
225
 
 
226
// *************************************************************************
 
227
 
 
228
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
229
void
 
230
SoQtFullViewer::setPopupMenuEnabled(const SbBool enable)
 
231
{
 
232
#if SOQT_DEBUG
 
233
  if ((enable && this->isPopupMenuEnabled()) ||
 
234
       (!enable && !this->isPopupMenuEnabled())) {
 
235
    SoDebugError::postWarning("SoQtFullViewer::setPopupMenuEnabled",
 
236
                              "popup menu already turned %s",
 
237
                              enable ? "on" : "off");
 
238
    return;
 
239
  }
 
240
#endif // SOQT_DEBUG
 
241
  PRIVATE(this)->menuenabled = enable;
 
242
}
 
243
 
 
244
// *************************************************************************
 
245
 
 
246
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
247
SbBool
 
248
SoQtFullViewer::isPopupMenuEnabled(void) const
 
249
{
 
250
  return PRIVATE(this)->menuenabled;
 
251
}
 
252
 
 
253
// *************************************************************************
 
254
 
 
255
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
256
QWidget *
 
257
SoQtFullViewer::getAppPushButtonParent(void) const
 
258
{
 
259
  return PRIVATE(this)->appbuttonform;
 
260
}
 
261
 
 
262
// *************************************************************************
 
263
 
 
264
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
265
void
 
266
SoQtFullViewer::addAppPushButton(QWidget * newButton)
 
267
{
 
268
  PRIVATE(this)->appbuttonlist->append(newButton);
 
269
  PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
 
270
}
 
271
 
 
272
// *************************************************************************
 
273
 
 
274
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
275
void
 
276
SoQtFullViewer::insertAppPushButton(QWidget * newButton, int index)
 
277
{
 
278
#if SOQT_DEBUG
 
279
  if ((index < 0) || (index > this->lengthAppPushButton())) {
 
280
    SoDebugError::postWarning("SoQtFullViewer::insertAppPushButton",
 
281
                              "index %d out of bounds", index);
 
282
    return;
 
283
  }
 
284
#endif // SOQT_DEBUG
 
285
  PRIVATE(this)->appbuttonlist->insert(newButton, index);
 
286
  PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
 
287
}
 
288
 
 
289
// *************************************************************************
 
290
 
 
291
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
292
void
 
293
SoQtFullViewer::removeAppPushButton(QWidget * oldButton)
 
294
{
 
295
  int idx = PRIVATE(this)->appbuttonlist->find(oldButton);
 
296
 
 
297
#if SOQT_DEBUG
 
298
  if (idx == -1) {
 
299
    SoDebugError::postWarning("SoQtFullViewer::removeAppPushButton",
 
300
                              "tried to remove non-existant button");
 
301
    return;
 
302
  }
 
303
#endif // SOQT_DEBUG
 
304
 
 
305
  PRIVATE(this)->appbuttonlist->remove(idx);
 
306
  PRIVATE(this)->layoutAppButtons(this->getAppPushButtonParent());
 
307
}
 
308
 
 
309
// *************************************************************************
 
310
 
 
311
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
312
int
 
313
SoQtFullViewer::findAppPushButton(QWidget * oldButton) const
 
314
{
 
315
  return PRIVATE(this)->appbuttonlist->find(oldButton);
 
316
}
 
317
 
 
318
// *************************************************************************
 
319
 
 
320
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
321
int
 
322
SoQtFullViewer::lengthAppPushButton(void) const
 
323
{
 
324
  return PRIVATE(this)->appbuttonlist->getLength();
 
325
}
 
326
 
 
327
// *************************************************************************
 
328
 
 
329
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
330
QWidget *
 
331
SoQtFullViewer::getRenderAreaWidget(void) const
 
332
{
 
333
  return PRIVATE(this)->canvas;
 
334
}
 
335
 
 
336
// *************************************************************************
 
337
 
 
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.
 
342
void
 
343
SoQtFullViewer::setViewing(SbBool enable)
 
344
{
 
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");
 
350
#endif // debug
 
351
    return;
 
352
  }
 
353
 
 
354
  inherited::setViewing(enable);
 
355
 
 
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);
 
362
  }
 
363
}
 
364
 
 
365
// *************************************************************************
 
366
 
 
367
// Documented in superclass.
 
368
QWidget *
 
369
SoQtFullViewer::buildWidget(QWidget * parent)
 
370
{
 
371
  // This will build the main view widgets, along with the decorations
 
372
  // widgets and popup menu if they are enabled.
 
373
 
 
374
#if SOQT_DEBUG && 0
 
375
  SoDebugError::postInfo("SoQtFullViewer::buildWidget", "[invoked]");
 
376
#endif
 
377
 
 
378
  PRIVATE(this)->viewerwidget = new QWidget(parent);
 
379
  this->registerWidget(PRIVATE(this)->viewerwidget);
 
380
 
 
381
  PRIVATE(this)->viewerwidget->move(0, 0);
 
382
 
 
383
#if SOQT_DEBUG && 0
 
384
  PRIVATE(this)->viewerwidget->setBackgroundColor(QColor(250, 0, 0));
 
385
#endif
 
386
 
 
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.
 
396
 
 
397
  PRIVATE(this)->canvas = inherited::buildWidget(PRIVATE(this)->viewerwidget);
 
398
 
 
399
  QSize s(PRIVATE(this)->viewerwidget->size().width(),
 
400
          PRIVATE(this)->viewerwidget->size().height());
 
401
 
 
402
  PRIVATE(this)->canvas->resize(s);
 
403
 
 
404
  this->buildDecoration( PRIVATE(this)->viewerwidget );
 
405
  PRIVATE(this)->showDecorationWidgets( PRIVATE(this)->decorations );
 
406
 
 
407
  if (PRIVATE(this)->menuenabled)
 
408
    this->buildPopupMenu();
 
409
 
 
410
  return PRIVATE(this)->viewerwidget;
 
411
}
 
412
 
 
413
// *************************************************************************
 
414
 
 
415
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
416
void
 
417
SoQtFullViewer::buildDecoration(QWidget * parent)
 
418
{
 
419
  this->leftDecoration = this->buildLeftTrim(parent);
 
420
  this->bottomDecoration = this->buildBottomTrim(parent);
 
421
  this->rightDecoration = this->buildRightTrim(parent);
 
422
}
 
423
 
 
424
// *************************************************************************
 
425
 
 
426
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
427
QWidget *
 
428
SoQtFullViewer::buildLeftTrim(QWidget * parent)
 
429
{
 
430
  QWidget * w = new QWidget(parent);
 
431
  w->setFixedWidth(30);
 
432
 
 
433
  QGridLayout * gl = new QGridLayout(w, 3, 1, 2, -1);
 
434
  gl->addWidget(this->buildAppButtons(w), 0, 0);
 
435
 
 
436
  SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Vertical, w);
 
437
  this->leftWheel = t;
 
438
  t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
 
439
  this->leftWheelVal = t->value();
 
440
 
 
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()));
 
444
 
 
445
  gl->addWidget(t, 2, 0, Qt::AlignBottom | Qt::AlignHCenter);
 
446
  gl->activate();
 
447
 
 
448
  return w;
 
449
}
 
450
 
 
451
// *************************************************************************
 
452
 
 
453
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
454
QWidget *
 
455
SoQtFullViewer::buildBottomTrim(QWidget * parent)
 
456
{
 
457
  QWidget * w = new QWidget(parent);
 
458
  w->setFixedHeight(30);
 
459
 
 
460
  QLabel * label = new QLabel(this->leftWheelStr, w);
 
461
  label->adjustSize();
 
462
  label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
 
463
  label->setMargin(2);
 
464
  this->leftWheelLabel = label;
 
465
 
 
466
  label = new QLabel(this->bottomWheelStr, w);
 
467
  label->adjustSize();
 
468
  label->setAlignment(Qt::AlignRight | Qt::AlignVCenter);
 
469
  label->setMargin(2);
 
470
  this->bottomWheelLabel = label;
 
471
 
 
472
  label = new QLabel(this->rightWheelStr, w);
 
473
  label->adjustSize();
 
474
  label->setAlignment(Qt::AlignRight | Qt::AlignTop);
 
475
  label->setMargin(2);
 
476
  this->rightWheelLabel = label;
 
477
 
 
478
  SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Horizontal, w);
 
479
  this->bottomWheel = t;
 
480
  t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
 
481
 
 
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()));
 
488
 
 
489
  this->bottomWheelVal = t->value();
 
490
 
 
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);
 
497
 
 
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);
 
502
 
 
503
  gl->activate();
 
504
 
 
505
  return w;
 
506
}
 
507
 
 
508
// *************************************************************************
 
509
 
 
510
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
511
QWidget *
 
512
SoQtFullViewer::buildRightTrim(QWidget * parent)
 
513
{
 
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
 
519
 
 
520
  SoQtThumbWheel * t = new SoQtThumbWheel(SoQtThumbWheel::Vertical, w);
 
521
  this->rightWheel = t;
 
522
  t->setRangeBoundaryHandling(SoQtThumbWheel::ACCUMULATE);
 
523
  this->rightWheelVal = t->value();
 
524
 
 
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()));
 
531
 
 
532
  QGridLayout * l = new QGridLayout(w, 3, 1, 2, -1);
 
533
  l->setMargin(0);
 
534
  l->addWidget(this->buildViewerButtons(w), 0, 0);
 
535
  l->addWidget(t, 2, 0, Qt::AlignBottom | Qt::AlignHCenter);
 
536
  l->activate();
 
537
 
 
538
  return w;
 
539
}
 
540
 
 
541
// *************************************************************************
 
542
 
 
543
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
544
QWidget *
 
545
SoQtFullViewer::buildAppButtons(QWidget * parent)
 
546
{
 
547
  PRIVATE(this)->appbuttonform = new QWidget(parent);
 
548
 
 
549
  if (this->lengthAppPushButton() > 0)
 
550
    PRIVATE(this)->layoutAppButtons(PRIVATE(this)->appbuttonform);
 
551
 
 
552
  return PRIVATE(this)->appbuttonform;
 
553
}
 
554
 
 
555
// *************************************************************************
 
556
 
 
557
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
558
QWidget *
 
559
SoQtFullViewer::buildViewerButtons(QWidget * parent)
 
560
{
 
561
  QWidget * w = new QWidget(parent);
 
562
  this->createViewerButtons(w, PRIVATE(this)->viewerbuttons);
 
563
  w->move(0, 0);
 
564
 
 
565
  // assert(PRIVATE(this)->viewerbuttons->getLength() != 0);
 
566
  QGridLayout * l =
 
567
    new QGridLayout(w, PRIVATE(this)->viewerbuttons->getLength(), 1);
 
568
  l->setMargin(0);
 
569
  l->setSpacing(0);
 
570
 
 
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);
 
577
  }
 
578
 
 
579
  l->activate();
 
580
  return w;
 
581
}
 
582
 
 
583
// *************************************************************************
 
584
 
 
585
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
586
void
 
587
SoQtFullViewer::createViewerButtons(QWidget * parent, SbPList * buttonlist)
 
588
{
 
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
 
592
    // the pushbuttons.
 
593
    p->setFocusPolicy(QWidget::NoFocus);
 
594
 
 
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); }
 
602
#endif
 
603
 
 
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.
 
609
 
 
610
    switch (i) {
 
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()));
 
618
      break;
 
619
    case EXAMINE_BUTTON:
 
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()));
 
626
      break;
 
627
    case HOME_BUTTON:
 
628
      QObject::connect(p, SIGNAL(clicked()), PRIVATE(this), SLOT(homebuttonClicked()));
 
629
      p->setPixmap(QPixmap((const char **)home_xpm));
 
630
      break;
 
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));
 
635
      break;
 
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));
 
640
      break;
 
641
    case SEEK_BUTTON:
 
642
      QObject::connect(p, SIGNAL(clicked()), PRIVATE(this), SLOT(seekbuttonClicked()));
 
643
      p->setPixmap(QPixmap((const char **)seek_xpm));
 
644
      break;
 
645
    default:
 
646
      assert(0);
 
647
      break;
 
648
    }
 
649
 
 
650
    p->adjustSize();
 
651
    buttonlist->append(p);
 
652
  }
 
653
}
 
654
 
 
655
// *************************************************************************
 
656
 
 
657
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
658
void
 
659
SoQtFullViewer::buildPopupMenu(void)
 
660
{
 
661
  this->prefmenu = PRIVATE(this)->setupStandardPopupMenu();
 
662
}
 
663
 
 
664
// *************************************************************************
 
665
 
 
666
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
667
void
 
668
SoQtFullViewer::openPopupMenu(const SbVec2s position)
 
669
{
 
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;
 
675
 
 
676
  PRIVATE(this)->prepareMenu(this->prefmenu);
 
677
  this->prefmenu->popUp(this->getGLWidget(), x, y);
 
678
}
 
679
 
 
680
// *************************************************************************
 
681
 
 
682
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
683
void
 
684
SoQtFullViewer::setLeftWheelString(const char * const string)
 
685
{
 
686
  delete [] this->leftWheelStr;
 
687
  this->leftWheelStr = NULL;
 
688
 
 
689
  if (string)
 
690
    this->leftWheelStr = strcpy(new char [strlen(string)+1], string);
 
691
  if (this->leftWheelLabel)
 
692
    ((QLabel *)this->leftWheelLabel)->setText(string ? string : "");
 
693
}
 
694
 
 
695
// *************************************************************************
 
696
 
 
697
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
698
void
 
699
SoQtFullViewer::setBottomWheelString(const char * const string)
 
700
{
 
701
  delete [] this->bottomWheelStr;
 
702
  this->bottomWheelStr = NULL;
 
703
 
 
704
  if (string)
 
705
    this->bottomWheelStr = strcpy(new char [strlen(string)+1], string);
 
706
  if (this->bottomWheelLabel)
 
707
    ((QLabel *)this->bottomWheelLabel)->setText(string ? string : "");
 
708
}
 
709
 
 
710
// *************************************************************************
 
711
 
 
712
// Documented in common/viewers/SoGuiFullViewer.cpp.in.
 
713
void
 
714
SoQtFullViewer::setRightWheelString(const char * const string)
 
715
{
 
716
  delete [] this->rightWheelStr;
 
717
  this->rightWheelStr = NULL;
 
718
 
 
719
  if (string)
 
720
    this->rightWheelStr = strcpy(new char [strlen(string)+1], string);
 
721
  if (this->rightWheelLabel)
 
722
    ((QLabel *)this->rightWheelLabel)->setText(string ? string : "");
 
723
}
 
724
 
 
725
// *************************************************************************
 
726
 
 
727
// doc in super
 
728
void
 
729
SoQtFullViewer::sizeChanged(const SbVec2s & size)
 
730
{
 
731
#if SOQT_DEBUG && 0
 
732
  SoDebugError::postInfo("SoQtFullViewer::sizeChanged", "(%d, %d)",
 
733
                         size[0], size[1]);
 
734
#endif
 
735
 
 
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;
 
741
  }
 
742
 
 
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):
 
745
  //
 
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
 
749
  // window blank...
 
750
#if defined Q_WS_MAC && ((QT_VERSION == 0x030100) || (QT_VERSION == 0x030101))
 
751
 
 
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)) {
 
756
 
 
757
    if (!PRIVATE(this)->decorations) { // GL context would fill whole window
 
758
      newsize -= SbVec2s(0, 15);       // -> leave lowermost 15 px blank
 
759
 
 
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");
 
773
      }
 
774
    }
 
775
  }
 
776
 
 
777
#endif
 
778
 
 
779
  newsize = SbVec2s(SoQtMax(newsize[0], (short)1),
 
780
                    SoQtMax(newsize[1], (short)1));
 
781
 
 
782
  inherited::sizeChanged(newsize);
 
783
}
 
784
 
 
785
// *************************************************************************
 
786
 
 
787
#ifndef DOXYGEN_SKIP_THIS
 
788
 
 
789
// Show or hide decorations. Will make and activate a Qt layout grid
 
790
// if we're turning the decorations on.
 
791
void
 
792
SoQtFullViewerP::showDecorationWidgets(SbBool onOff)
 
793
{
 
794
#if SOQT_DEBUG && 0
 
795
  SoDebugError::postInfo("SoQtFullViewerP::showDecorationWidgets", "[invoked]");
 
796
#endif // SOQT_DEBUG
 
797
 
 
798
  if (this->mainlayout) delete this->mainlayout;
 
799
 
 
800
  assert(this->viewerwidget);
 
801
//  assert(this->canvasparent);
 
802
 
 
803
  assert(PUBLIC(this)->leftDecoration && PUBLIC(this)->bottomDecoration && PUBLIC(this)->rightDecoration);
 
804
  if (onOff) {
 
805
    PUBLIC(this)->leftDecoration->show();
 
806
    PUBLIC(this)->bottomDecoration->show();
 
807
    PUBLIC(this)->rightDecoration->show();
 
808
 
 
809
    QGridLayout * g = new QGridLayout(this->viewerwidget, 2, 1, 0, -1); // VIEWERBORDER);
 
810
 
 
811
    g->addWidget(PUBLIC(this)->bottomDecoration, 1, 0);
 
812
 
 
813
    QGridLayout * subLayout = new QGridLayout(1, 3, 0);
 
814
    g->addLayout(subLayout, 0, 0);
 
815
 
 
816
    subLayout->addWidget(PUBLIC(this)->leftDecoration, 0, 0);
 
817
    subLayout->addWidget(this->canvas, 0, 1);
 
818
    subLayout->addWidget(PUBLIC(this)->rightDecoration, 0, 2);
 
819
 
 
820
//     subLayout->setColStretch(1, 1);
 
821
//     g->setRowStretch(0, 1);
 
822
 
 
823
    this->mainlayout = g;
 
824
  } else {
 
825
    QGridLayout * g = new QGridLayout(this->viewerwidget, 1, 1, 0, -1);
 
826
    g->addWidget(this->canvas, 0, 0);
 
827
    this->mainlayout = g;
 
828
 
 
829
    PUBLIC(this)->leftDecoration->hide();
 
830
    PUBLIC(this)->bottomDecoration->hide();
 
831
    PUBLIC(this)->rightDecoration->hide();
 
832
  }
 
833
 
 
834
  this->mainlayout->activate();
 
835
  QSize size = this->viewerwidget->size();
 
836
  SbVec2s rasize = SbVec2s(size.width(), size.height());
 
837
  PUBLIC(this)->sizeChanged(rasize);
 
838
}
 
839
 
 
840
// *************************************************************************
 
841
 
 
842
// Layout application specified buttons.
 
843
void
 
844
SoQtFullViewerP::layoutAppButtons(QWidget * form)
 
845
{
 
846
  delete this->appbuttonlayout; this->appbuttonlayout = NULL;
 
847
 
 
848
  int nrbuttons = this->appbuttonlist->getLength();
 
849
  if (nrbuttons == 0) return;
 
850
 
 
851
  this->appbuttonlayout = new QGridLayout(form, nrbuttons, 1);
 
852
 
 
853
  for (int i=0; i < nrbuttons; i++) {
 
854
    QWidget * button = (QWidget *)((*(this->appbuttonlist))[i]);
 
855
    button->show();
 
856
    ((QGridLayout *)this->appbuttonlayout)->addWidget(button, i, 0);
 
857
  }
 
858
 
 
859
  this->appbuttonlayout->activate();
 
860
}
 
861
 
 
862
// *************************************************************************
 
863
 
 
864
// Qt slot.
 
865
void
 
866
SoQtFullViewerP::interactbuttonClicked(void)
 
867
{
 
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);
 
874
}
 
875
 
 
876
// *************************************************************************
 
877
 
 
878
// Qt slot.
 
879
void
 
880
SoQtFullViewerP::viewbuttonClicked(void)
 
881
{
 
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);
 
888
}
 
889
 
 
890
// *************************************************************************
 
891
 
 
892
// Qt slot.
 
893
void
 
894
SoQtFullViewerP::homebuttonClicked()
 
895
{
 
896
  PUBLIC(this)->resetToHomePosition();
 
897
}
 
898
 
 
899
// *************************************************************************
 
900
 
 
901
// Qt slot.
 
902
void
 
903
SoQtFullViewerP::sethomebuttonClicked()
 
904
{
 
905
  PUBLIC(this)->saveHomePosition();
 
906
}
 
907
 
 
908
// *************************************************************************
 
909
 
 
910
// Qt slot.
 
911
void
 
912
SoQtFullViewerP::viewallbuttonClicked()
 
913
{
 
914
  PUBLIC(this)->viewAll();
 
915
}
 
916
 
 
917
// *************************************************************************
 
918
 
 
919
// Qt slot.
 
920
void
 
921
SoQtFullViewerP::seekbuttonClicked()
 
922
{
 
923
  PUBLIC(this)->setSeekMode(PUBLIC(this)->isSeekMode() ? FALSE : TRUE);
 
924
}
 
925
 
 
926
// *************************************************************************
 
927
 
 
928
// Qt slot.
 
929
void
 
930
SoQtFullViewerP::selectedViewing()
 
931
{
 
932
  PUBLIC(this)->setViewing(PUBLIC(this)->isViewing() ? FALSE : TRUE);
 
933
}
 
934
 
 
935
// *************************************************************************
 
936
 
 
937
// Qt slot.
 
938
void
 
939
SoQtFullViewerP::selectedDecoration()
 
940
{
 
941
  PUBLIC(this)->setDecoration(PUBLIC(this)->isDecoration() ? FALSE : TRUE);
 
942
}
 
943
 
 
944
// *************************************************************************
 
945
 
 
946
// Qt slot.
 
947
void
 
948
SoQtFullViewerP::selectedHeadlight()
 
949
{
 
950
  PUBLIC(this)->setHeadlight(PUBLIC(this)->isHeadlight() ? FALSE : TRUE);
 
951
}
 
952
 
 
953
// *************************************************************************
 
954
 
 
955
// Qt slot.
 
956
void
 
957
SoQtFullViewerP::increaseInteractiveCount()
 
958
{
 
959
  PUBLIC(this)->interactiveCountInc();
 
960
}
 
961
 
 
962
// *************************************************************************
 
963
 
 
964
// Qt slot.
 
965
void
 
966
SoQtFullViewerP::decreaseInteractiveCount()
 
967
{
 
968
  PUBLIC(this)->interactiveCountDec();
 
969
}
 
970
 
 
971
// *************************************************************************
 
972
 
 
973
SoQtFullViewerP::SoQtFullViewerP(SoQtFullViewer * publ)
 
974
  : SoGuiFullViewerP(publ)
 
975
{
 
976
}
 
977
 
 
978
SoQtFullViewerP::~SoQtFullViewerP()
 
979
{
 
980
}
 
981
 
 
982
void
 
983
SoQtFullViewerP::setThumbWheelValue(void * wheel, float val)
 
984
{
 
985
  ((SoQtThumbWheel *)wheel)->setValue(val);
 
986
}
 
987
 
 
988
// *************************************************************************
 
989
 
 
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(); }
 
1000
 
 
1001
// *************************************************************************
 
1002
 
 
1003
#endif // DOXYGEN_SKIP_THIS