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#ifdef HAVE_CONFIG_H
36#include <config.h>
37#endif // HAVE_CONFIG_H
38
39#include <Inventor/errors/SoDebugError.h>
40#include <Inventor/elements/SoLazyElement.h>
41#include <Inventor/misc/SoState.h>
42#include <Inventor/actions/SoGLRenderAction.h>
43#include <Inventor/nodes/SoSeparator.h>
44#include <Inventor/nodes/SoCoordinate3.h>
45#include <Inventor/nodes/SoMaterial.h>
46#include <Inventor/sensors/SoFieldSensor.h>
47
48#include <Inventor/@Gui@/common/gl.h>
49#include <Inventor/@Gui@/SoAny.h>
50#include <Inventor/@Gui@/nodes/SoGuiFrame.h>
51#include <assert.h>
52
53// *************************************************************************
54
55class Frame {
56public:
57  SoGuiFrame * api;
58
59  SoCoordinate3 * coords;
60  SoMaterial * light;
61  SoMaterial * shade;
62
63  SoFieldSensor * size_sensor;
64  SoFieldSensor * width_sensor;
65  static void size_updated_cb(void * closure, SoSensor * sensor);
66
67  SoFieldSensor * design_sensor;
68  static void design_updated_cb(void * closure, SoSensor * sensor);
69  SoFieldSensor * complement_sensor;
70
71  static const char * scene[];
72};
73
74// *************************************************************************
75
76#define PRIVATE(obj) ((Frame *)obj->internals)
77
78void
79SoGuiFrame::initClass(void)
80{
81  SO_KIT_INIT_CLASS(SoGuiFrame, SoBaseKit, "BaseKit");
82}
83
84SO_KIT_SOURCE(SoGuiFrame);
85
86SoGuiFrame::SoGuiFrame(void)
87{
88  this->internals = new Frame;
89  PRIVATE(this)->api = this;
90
91  SO_KIT_CONSTRUCTOR(SoGuiFrame);
92
93  SO_KIT_ADD_FIELD(size, (SbVec3f(0.0f, 0.0f, 0.0f)));
94  SO_KIT_ADD_FIELD(design, (SoGuiFrame::BLACK));
95  SO_KIT_ADD_FIELD(width, (1.0f));
96  SO_KIT_ADD_FIELD(complement, (FALSE));
97
98  SO_KIT_DEFINE_ENUM_VALUE(FrameDesign, BLACK);
99  SO_KIT_DEFINE_ENUM_VALUE(FrameDesign, COLOR);
100  SO_KIT_DEFINE_ENUM_VALUE(FrameDesign, EMBOSS);
101
102  SO_KIT_SET_SF_ENUM_TYPE(design, FrameDesign);
103
104  SO_KIT_ADD_CATALOG_ENTRY(scene, SoSeparator, TRUE, this, "", FALSE);
105
106  SO_KIT_INIT_INSTANCE();
107
108  SoNode * node = SoAny::loadSceneGraph(Frame::scene);
109  assert(node);
110
111  this->setAnyPart("scene", node);
112
113  PRIVATE(this)->coords = (SoCoordinate3 *) SoAny::scanSceneForName(node, "coordinates");
114  PRIVATE(this)->light = (SoMaterial *) SoAny::scanSceneForName(node, "light");
115  PRIVATE(this)->shade = (SoMaterial *) SoAny::scanSceneForName(node, "shade");
116
117  assert(PRIVATE(this)->coords);
118  assert(PRIVATE(this)->light);
119  assert(PRIVATE(this)->shade);
120
121  PRIVATE(this)->coords->ref();
122  PRIVATE(this)->light->ref();
123  PRIVATE(this)->shade->ref();
124
125  PRIVATE(this)->size_sensor = new SoFieldSensor(Frame::size_updated_cb, PRIVATE(this));
126  PRIVATE(this)->size_sensor->attach(&(this->size));
127  PRIVATE(this)->width_sensor = new SoFieldSensor(Frame::size_updated_cb, PRIVATE(this));
128  PRIVATE(this)->width_sensor->attach(&(this->size));
129  PRIVATE(this)->design_sensor = new SoFieldSensor(Frame::design_updated_cb, PRIVATE(this));
130  PRIVATE(this)->design_sensor->attach(&(this->design));
131  PRIVATE(this)->complement_sensor = new SoFieldSensor(Frame::design_updated_cb, PRIVATE(this));
132  PRIVATE(this)->complement_sensor->attach(&(this->complement));
133  this->design.touch();
134}
135
136SoGuiFrame::~SoGuiFrame(void)
137{
138  PRIVATE(this)->coords->unref();
139  PRIVATE(this)->light->unref();
140  PRIVATE(this)->shade->unref();
141  delete PRIVATE(this)->size_sensor;
142  delete PRIVATE(this)->width_sensor;
143  delete PRIVATE(this)->design_sensor;
144  delete PRIVATE(this)->complement_sensor;
145  Frame * obj = PRIVATE(this);
146  delete obj;
147}
148
149#undef PRIVATE
150
151// *************************************************************************
152
153#define PUBLIC(obj) ((SoGuiFrame *)obj->api)
154
155const char *
156Frame::scene[] =
157{
158  "#Inventor V2.1 ascii",
159  "",
160  "Separator {",
161  "  DEF coordinates Coordinate3 {",
162  "    point [",
163  "      0 0 0,",
164  "      1 0 0,",
165  "      1 1 0,",
166  "      0 1 0,",
167  "      -1 -1 0,",
168  "      2 -1 0,",
169  "      2 2 0,",
170  "      -1 2 0",
171  "    ]",
172  "  }",
173  // shadow
174  "  DEF shade Material {",
175  "    diffuseColor 0.9 0.9 0.9",
176  "  }",
177  "  IndexedFaceSet {",
178  "    coordIndex [",
179  "      4 5 1 -1",
180  "      4 1 0 -1",
181  "      5 6 2 -1",
182  "      5 2 1 -1",
183  "    ]",
184  "  }",
185  // light
186  "  DEF light Material {",
187  "    diffuseColor 0.5 0.5 0.5",
188  "  }",
189  "  IndexedFaceSet {",
190  "    coordIndex [",
191  "      6 7 3 -1",
192  "      6 3 2 -1",
193  "      7 4 0 -1",
194  "      7 0 3 -1",
195  "    ]",
196  "  }",
197  "}",
198  NULL
199};
200
201void
202Frame::size_updated_cb(void * closure, SoSensor * sensor)
203{
204  assert(closure != NULL);
205  Frame * me = (Frame *) closure;
206  SoCoordinate3 * coords = me->coords;
207  assert(coords);
208  SbVec3f size = PUBLIC(me)->size.getValue();
209  float width = PUBLIC(me)->width.getValue();
210  SbBool save = coords->point.enableNotify(FALSE);
211  coords->point.set1Value(1, SbVec3f(size[0], 0.0f, 0.0f));
212  coords->point.set1Value(2, SbVec3f(size[0], size[1], 0.0f));
213  coords->point.set1Value(3, SbVec3f(0.0f, size[1], 0.0f));
214  coords->point.set1Value(4, SbVec3f(-width, -width, 0.0f));
215  coords->point.set1Value(5, SbVec3f(size[0]+width, -width, 0.0f));
216  coords->point.set1Value(6, SbVec3f(size[0]+width, size[1]+width, 0.0f));
217  coords->point.set1Value(7, SbVec3f(-width, size[1]+width, 0.0f));
218  coords->point.enableNotify(save);
219  if ( save ) coords->point.touch();
220}
221
222void
223Frame::design_updated_cb(void * closure, SoSensor * sensor)
224{
225  assert(closure != NULL);
226  Frame * me = (Frame *) closure;
227  SoMaterial * light = me->light;
228  SoMaterial * shade = me->shade;
229  assert(light);
230  assert(shade);
231  switch ( PUBLIC(me)->design.getValue() ) {
232  case SoGuiFrame::EMBOSS:
233    if ( PUBLIC(me)->complement.getValue() ) {
234      light->diffuseColor.setValue(SbColor(0.5f, 0.5f, 0.5f));
235      shade->diffuseColor.setValue(SbColor(0.9f, 0.9f, 0.9f));
236    } else {
237      light->diffuseColor.setValue(SbColor(0.9f, 0.9f, 0.9f));
238      shade->diffuseColor.setValue(SbColor(0.5f, 0.5f, 0.5f));
239    }
240    break;
241  case SoGuiFrame::BLACK:
242    if ( PUBLIC(me)->complement.getValue() ) {
243      light->diffuseColor.setValue(SbColor(1.0f, 0.0f, 0.0f));
244      shade->diffuseColor.setValue(SbColor(1.0f, 0.0f, 0.0f));
245    } else {
246      light->diffuseColor.setValue(SbColor(0.0f, 0.0f, 0.0f));
247      shade->diffuseColor.setValue(SbColor(0.0f, 0.0f, 0.0f));
248    }
249    break;
250  default:
251    break;
252  }
253}
254
255#undef PUBLIC
256
257// *************************************************************************
258