1// @configure_input@
2
3/**************************************************************************\
4 *
5 *  This file is part of the Coin 3D visualization library.
6 *  Copyright (C) by Kongsberg Oil & Gas Technologies.
7 *
8 *  This library is free software; you can redistribute it and/or
9 *  modify it under the terms of the GNU General Public License
10 *  ("GPL") version 2 as published by the Free Software Foundation.
11 *  See the file LICENSE.GPL at the root directory of this source
12 *  distribution for additional information about the GNU GPL.
13 *
14 *  For using Coin with software that can not be combined with the GNU
15 *  GPL, and for taking advantage of the additional benefits of our
16 *  support services, please contact Kongsberg Oil & Gas Technologies
17 *  about acquiring a Coin Professional Edition License.
18 *
19 *  See http://www.coin3d.org/ for more information.
20 *
21 *  Kongsberg Oil & Gas Technologies, Bygdoy Alle 5, 0257 Oslo, NORWAY.
22 *  http://www.sim.no/  sales@sim.no  coin-support@coin3d.org
23 *
24\**************************************************************************/
25
26#include <Inventor/actions/SoHandleEventAction.h>
27#include <Inventor/nodes/SoSeparator.h>
28#include <Inventor/nodes/SoCoordinate3.h>
29#include <Inventor/sensors/SoFieldSensor.h>
30#include <Inventor/events/SoMouseButtonEvent.h>
31#include <Inventor/SoPickedPoint.h>
32
33#include <Inventor/@Gui@/SoAny.h>
34#include <Inventor/@Gui@/nodes/SoGuiToggleButton.h>
35#include <assert.h>
36
37// *************************************************************************
38
39class ToggleButton {
40public:
41  ToggleButton(void);
42
43  SoGuiToggleButton * api;
44
45  SoCoordinate3 * coords;
46  SoNode * faceset;
47  SoFieldSensor * size_sensor;
48  static void size_updated_cb(void * closure, SoSensor * sensor);
49
50  static const char * scene[];
51};
52
53// *************************************************************************
54
55#define PRIVATE(obj) ((ToggleButton *)obj->internals)
56
57void
58SoGuiToggleButton::initClass(void)
59{
60  SO_KIT_INIT_CLASS(SoGuiToggleButton, SoBaseKit, "BaseKit");
61}
62
63SO_KIT_SOURCE(SoGuiToggleButton);
64
65SoGuiToggleButton::SoGuiToggleButton(void)
66{
67  this->internals = new ToggleButton;
68  PRIVATE(this)->api = this;
69
70  SO_KIT_CONSTRUCTOR(SoGuiToggleButton);
71
72  SO_KIT_ADD_FIELD(size, (SbVec3f(1.0f, 1.0f, 0.0f)));
73  SO_KIT_ADD_FIELD(on, (FALSE));
74
75  SO_KIT_ADD_CATALOG_ENTRY(root, SoSeparator, FALSE, this, "", FALSE);
76
77  SO_KIT_INIT_INSTANCE();
78
79  SoNode * scene = SoAny::loadSceneGraph(ToggleButton::scene);
80  assert(scene);
81  assert(scene->isOfType(SoSeparator::getClassTypeId()));
82  scene->ref();
83
84  PRIVATE(this)->coords = (SoCoordinate3 *) SoAny::scanSceneForName(scene, "coords");
85  assert(PRIVATE(this)->coords);
86  assert(PRIVATE(this)->coords->isOfType(SoCoordinate3::getClassTypeId()));
87  PRIVATE(this)->faceset = SoAny::scanSceneForName(scene, "faceset");
88  assert(PRIVATE(this)->faceset);
89
90  scene->unrefNoDelete();
91  this->setAnyPart("root", scene);
92
93  PRIVATE(this)->size_sensor = new SoFieldSensor(ToggleButton::size_updated_cb, PRIVATE(this));
94  PRIVATE(this)->size_sensor->attach(&(this->size));
95}
96
97
98SoGuiToggleButton::~SoGuiToggleButton(void)
99{
100  delete PRIVATE(this)->size_sensor;
101  ToggleButton * obj = PRIVATE(this);
102  delete obj;
103}
104
105void
106SoGuiToggleButton::handleEvent(SoHandleEventAction * action)
107{
108  const SoEvent * ev = action->getEvent();
109  if ( ev->isOfType(SoMouseButtonEvent::getClassTypeId()) ) {
110    SbBool hit = FALSE;
111    const SoPickedPointList & ppoints = action->getPickedPointList();
112    assert(PRIVATE(this)->faceset);
113    int i = 0;
114    for ( i = 0; !hit && i < ppoints.getLength(); i++ ) {
115      const SoPickedPoint * point = ppoints[i];
116      const SoFullPath * path = (const SoFullPath *) point->getPath();
117      assert(path);
118      SoNode * node = path->getTail();
119      if ( node == PRIVATE(this)->faceset ) hit = TRUE;
120    }
121    if ( hit ) {
122      const SoMouseButtonEvent * event = (SoMouseButtonEvent *) ev;
123      if ( event->getState() == SoButtonEvent::DOWN ) {
124        if ( this->on.getValue() ) {
125          this->on.setValue(FALSE);
126        } else {
127          this->on.setValue(TRUE);
128        }
129        action->setHandled();
130      }
131    }
132  }
133  if ( !action->isHandled() ) {
134    inherited::handleEvent(action);
135  }
136}
137
138#undef PRIVATE
139
140// *************************************************************************
141// ToggleButton
142// *************************************************************************
143
144#define PUBLIC(obj) (obj->api)
145
146const char *
147ToggleButton::scene[] =
148{
149  "#Inventor V2.1 ascii",
150  "",
151  "Separator {",
152  "  DEF coords Coordinate3 {",
153  "    point [",
154  "      0 0 0,",
155  "      1 0 0,",
156  "      1 1 0,",
157  "      0 1 0",
158  "    ]",
159  "  }",
160  "  DEF faceset IndexedFaceSet {",
161  "    coordIndex [",
162  "      0 1 2 -1",
163  "      0 2 3 -1",
164  "    ]",
165  "  }",
166  "}",
167  NULL
168};
169
170ToggleButton::ToggleButton(void)
171{
172  this->api = NULL;
173  this->coords = NULL;
174  this->size_sensor = NULL;
175}
176
177void
178ToggleButton::size_updated_cb(void * closure, SoSensor * sensor)
179{
180  assert(closure);
181  ToggleButton * me = (ToggleButton *) closure;
182  assert(PUBLIC(me));
183  SbVec3f size = PUBLIC(me)->size.getValue();
184  assert(me->size_sensor);
185  me->size_sensor->detach();
186  assert(me->coords);
187  SbBool save = me->coords->point.enableNotify(FALSE);
188  me->coords->point.set1Value(0, SbVec3f(0.0f, 0.0f, 0.0f));
189  me->coords->point.set1Value(1, SbVec3f(size[0], 0.0f, 0.0f));
190  me->coords->point.set1Value(2, SbVec3f(size[0], size[1], 0.0f));
191  me->coords->point.set1Value(3, SbVec3f(0.0f, size[1], 0.0f));
192  me->coords->enableNotify(save);
193  if ( save ) me->coords->point.touch();
194  me->size_sensor->attach(&(PUBLIC(me)->size));
195}
196
197#undef PUBLIC
198
199// *************************************************************************
200