1// @configure_input@
2
3/**************************************************************************\
4 * Copyright (c) Kongsberg Oil & Gas Technologies AS
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are
9 * met:
10 *
11 * Redistributions of source code must retain the above copyright notice,
12 * this list of conditions and the following disclaimer.
13 *
14 * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 *
18 * Neither the name of the copyright holder nor the names of its
19 * contributors may be used to endorse or promote products derived from
20 * this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33\**************************************************************************/
34
35#include <Inventor/actions/SoHandleEventAction.h>
36#include <Inventor/nodes/SoSeparator.h>
37#include <Inventor/nodes/SoCoordinate3.h>
38#include <Inventor/sensors/SoFieldSensor.h>
39#include <Inventor/events/SoMouseButtonEvent.h>
40#include <Inventor/SoPickedPoint.h>
41
42#include <Inventor/@Gui@/SoAny.h>
43#include <Inventor/@Gui@/nodes/SoGuiToggleButton.h>
44#include <assert.h>
45
46// *************************************************************************
47
48class ToggleButton {
49public:
50  ToggleButton(void);
51
52  SoGuiToggleButton * api;
53
54  SoCoordinate3 * coords;
55  SoNode * faceset;
56  SoFieldSensor * size_sensor;
57  static void size_updated_cb(void * closure, SoSensor * sensor);
58
59  static const char * scene[];
60};
61
62// *************************************************************************
63
64#define PRIVATE(obj) ((ToggleButton *)obj->internals)
65
66void
67SoGuiToggleButton::initClass(void)
68{
69  SO_KIT_INIT_CLASS(SoGuiToggleButton, SoBaseKit, "BaseKit");
70}
71
72SO_KIT_SOURCE(SoGuiToggleButton);
73
74SoGuiToggleButton::SoGuiToggleButton(void)
75{
76  this->internals = new ToggleButton;
77  PRIVATE(this)->api = this;
78
79  SO_KIT_CONSTRUCTOR(SoGuiToggleButton);
80
81  SO_KIT_ADD_FIELD(size, (SbVec3f(1.0f, 1.0f, 0.0f)));
82  SO_KIT_ADD_FIELD(on, (FALSE));
83
84  SO_KIT_ADD_CATALOG_ENTRY(root, SoSeparator, FALSE, this, "", FALSE);
85
86  SO_KIT_INIT_INSTANCE();
87
88  SoNode * scene = SoAny::loadSceneGraph(ToggleButton::scene);
89  assert(scene);
90  assert(scene->isOfType(SoSeparator::getClassTypeId()));
91  scene->ref();
92
93  PRIVATE(this)->coords = (SoCoordinate3 *) SoAny::scanSceneForName(scene, "coords");
94  assert(PRIVATE(this)->coords);
95  assert(PRIVATE(this)->coords->isOfType(SoCoordinate3::getClassTypeId()));
96  PRIVATE(this)->faceset = SoAny::scanSceneForName(scene, "faceset");
97  assert(PRIVATE(this)->faceset);
98
99  scene->unrefNoDelete();
100  this->setAnyPart("root", scene);
101
102  PRIVATE(this)->size_sensor = new SoFieldSensor(ToggleButton::size_updated_cb, PRIVATE(this));
103  PRIVATE(this)->size_sensor->attach(&(this->size));
104}
105
106
107SoGuiToggleButton::~SoGuiToggleButton(void)
108{
109  delete PRIVATE(this)->size_sensor;
110  ToggleButton * obj = PRIVATE(this);
111  delete obj;
112}
113
114void
115SoGuiToggleButton::handleEvent(SoHandleEventAction * action)
116{
117  const SoEvent * ev = action->getEvent();
118  if ( ev->isOfType(SoMouseButtonEvent::getClassTypeId()) ) {
119    SbBool hit = FALSE;
120    const SoPickedPointList & ppoints = action->getPickedPointList();
121    assert(PRIVATE(this)->faceset);
122    int i = 0;
123    for ( i = 0; !hit && i < ppoints.getLength(); i++ ) {
124      const SoPickedPoint * point = ppoints[i];
125      const SoFullPath * path = (const SoFullPath *) point->getPath();
126      assert(path);
127      SoNode * node = path->getTail();
128      if ( node == PRIVATE(this)->faceset ) hit = TRUE;
129    }
130    if ( hit ) {
131      const SoMouseButtonEvent * event = (SoMouseButtonEvent *) ev;
132      if ( event->getState() == SoButtonEvent::DOWN ) {
133        if ( this->on.getValue() ) {
134          this->on.setValue(FALSE);
135        } else {
136          this->on.setValue(TRUE);
137        }
138        action->setHandled();
139      }
140    }
141  }
142  if ( !action->isHandled() ) {
143    inherited::handleEvent(action);
144  }
145}
146
147#undef PRIVATE
148
149// *************************************************************************
150// ToggleButton
151// *************************************************************************
152
153#define PUBLIC(obj) (obj->api)
154
155const char *
156ToggleButton::scene[] =
157{
158  "#Inventor V2.1 ascii",
159  "",
160  "Separator {",
161  "  DEF coords Coordinate3 {",
162  "    point [",
163  "      0 0 0,",
164  "      1 0 0,",
165  "      1 1 0,",
166  "      0 1 0",
167  "    ]",
168  "  }",
169  "  DEF faceset IndexedFaceSet {",
170  "    coordIndex [",
171  "      0 1 2 -1",
172  "      0 2 3 -1",
173  "    ]",
174  "  }",
175  "}",
176  NULL
177};
178
179ToggleButton::ToggleButton(void)
180{
181  this->api = NULL;
182  this->coords = NULL;
183  this->size_sensor = NULL;
184}
185
186void
187ToggleButton::size_updated_cb(void * closure, SoSensor * sensor)
188{
189  assert(closure);
190  ToggleButton * me = (ToggleButton *) closure;
191  assert(PUBLIC(me));
192  SbVec3f size = PUBLIC(me)->size.getValue();
193  assert(me->size_sensor);
194  me->size_sensor->detach();
195  assert(me->coords);
196  SbBool save = me->coords->point.enableNotify(FALSE);
197  me->coords->point.set1Value(0, SbVec3f(0.0f, 0.0f, 0.0f));
198  me->coords->point.set1Value(1, SbVec3f(size[0], 0.0f, 0.0f));
199  me->coords->point.set1Value(2, SbVec3f(size[0], size[1], 0.0f));
200  me->coords->point.set1Value(3, SbVec3f(0.0f, size[1], 0.0f));
201  me->coords->enableNotify(save);
202  if ( save ) me->coords->point.touch();
203  me->size_sensor->attach(&(PUBLIC(me)->size));
204}
205
206#undef PUBLIC
207
208// *************************************************************************
209