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