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